Skip to contentSkip to conversation

b43-asm, b43-dasm: Add 5 new instructions.

PATCH New Francesco Gringoli 3 participants 19 messages Sep 12, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Regards,
-Francesco

-------------=--------------
Description of the new instructions

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

Opcode 0x0D6|1: jumps if the difference between op1 and op2 is positive or null.
Suggested name "jdpz" (jump if difference is positive or zero).

Opcode 0x0D8: jumps if the difference between op1 and op2 is positive. Suggested name "jdp" (jump if difference is positive).

Opcode 0x0D8|1: jumps if the difference between op1 and op2 is negative or null.
Suggested name "jdnz" (jump if difference is negative or zero).

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).
This works on CPUs running ucode11. I have tested it on CPUs running ucode5 and op3 is not assigned.

-------------=--------------
The following changes are made to b43-tools

1) b43-asm assembles new instructions jdn, jdnz, jdp, jdpz, mul;
2) b43-dasm disassembles opcodes 0xD6, 0xD7, 0xD8, 0xD9, 0x101.

main.c +0 -0
Index: assembler/main.c
===================================================================
@@ -737,6 +737,9 @@

? unsigned int opcode;
?
? switch (insn->op) {
+ ? ? ? ?case OP_MUL:
+ ? ? ? ? ? ? ? ?do_assemble_insn(ctx, insn, 0x101);
+ ? ? ? ? ? ? ? ?break;
? case OP_ADD:
? do_assemble_insn(ctx, insn, 0x1C0);
? break;
@@ -855,6 +858,22 @@
? out = do_assemble_insn(ctx, insn, 0x0DC | 0x1);
? out->is_jump_insn = 1;
? break;
+ ? ? ? ?case OP_JDN:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D6);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDPZ:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D6 | 0x1);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDP:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D8);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDNZ:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D8 | 0x1);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
? case OP_JZX:
? opcode = merge_ext_into_opcode(ctx, 0x400, insn);
? out = do_assemble_insn(ctx, insn, opcode);

parser.y +0 -0
Index: assembler/parser.y
===================================================================
@@ -43,7 +43,7 @@

?
?%token EQUAL NOT_EQUAL LOGICAL_OR LOGICAL_AND PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT
?
-%token OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE +%token OP_MUL OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE ?
?%token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32 IVAL_TRAM
?
@@ -176,6 +176,13 @@
? s->u.label = $1;
? $$ = s;
? ?}
+ ? ? ? ? ? ? ? ?| insn_mul {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
? | insn_add {
? struct statement *s = xmalloc(sizeof(struct statement));
? INIT_LIST_HEAD(&s->list);
@@ -393,6 +400,34 @@
? s->u.insn = $1;
? $$ = s;
? ?}
+ ? ? ? ? ? ? ? ?| insn_jdn {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdpz {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdp {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdnz {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
? | insn_jl {
? struct statement *s = xmalloc(sizeof(struct statement));
? INIT_LIST_HEAD(&s->list);
@@ -591,6 +626,15 @@
? ?}
? ;
?
+/* multiply */
+insn_mul : OP_MUL operlist_3 {
+ struct instruction *insn = xmalloc(sizeof(struct instruction));
+ insn->op = OP_MUL;
+ insn->operands = $2;
+ $$ = insn;
+ ?}
+ ;
+
?/* add */
?insn_add : OP_ADD operlist_3 {
? struct instruction *insn = xmalloc(sizeof(struct instruction));
@@ -897,6 +941,38 @@
? ?}
? ;
?
+insn_jdn : OP_JDN operlist_3 {
+ struct instruction *insn = xmalloc(sizeof(struct instruction));
+ insn->op = OP_JDN;
+ insn->operands = $2;
+ $$ = insn;
+ ?}
+ ;
+
+insn_jdpz : OP_JDPZ operlist_3 {
+ struct instruction *insn = xmalloc(sizeof(struct instruction));
+ insn->op = OP_JDPZ;
+ insn->operands = $2;
+ $$ = insn;
+ ?}
+ ;
+
+insn_jdp : OP_JDP operlist_3 {
+ struct instruction *insn = xmalloc(sizeof(struct instruction));
+ insn->op = OP_JDP;
+ insn->operands = $2;
+ $$ = insn;
+ ?}
+ ;
+
+insn_jdnz : OP_JDNZ operlist_3 {
+ struct instruction *insn = xmalloc(sizeof(struct instruction));
+ insn->op = OP_JDNZ;
+ insn->operands = $2;
+ $$ = insn;
+ ?}
+ ;
+
?insn_jext : OP_JEXT external_jump_operands {
? struct instruction *insn = xmalloc(sizeof(struct instruction));
? insn->op = OP_JEXT;

scanner.l +0 -0
Index: assembler/scanner.l
===================================================================
@@ -82,6 +82,8 @@

?\<\< { update_lineinfo(); return LEFTSHIFT; }
?\>\> { update_lineinfo(); return RIGHTSHIFT; }
?
+mul { update_lineinfo(); return OP_MUL; }
+
?add { update_lineinfo(); return OP_ADD; }
?add\. { update_lineinfo(); return OP_ADDSC; }
?addc { update_lineinfo(); return OP_ADDC; }
@@ -120,6 +122,10 @@
?jge { update_lineinfo(); return OP_JGE; }
?jg { update_lineinfo(); return OP_JG; }
?jle { update_lineinfo(); return OP_JLE; }
+jdn { update_lineinfo(); return OP_JDN; }
+jdpz { update_lineinfo(); return OP_JDPZ; }
+jdp { update_lineinfo(); return OP_JDP; }
+jdnz { update_lineinfo(); return OP_JDNZ; }
?jzx { update_lineinfo(); return OP_JZX; }
?jnzx { update_lineinfo(); return OP_JNZX; }
?jext { update_lineinfo(); return OP_JEXT; }

main.c +0 -0
Index: disassembler/main.c
===================================================================
@@ -284,6 +284,12 @@

? struct bin_instruction *bin = stmt->u.insn.bin;
?
? switch (bin->opcode) {
+ case 0x101:
+ stmt->u.insn.name = "mul";
+ disasm_std_operand(stmt, 0, 0);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 1, 1);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 2, 2);
+ break;
? case 0x1C0:
? stmt->u.insn.name = "add";
? disasm_std_operand(stmt, 0, 0);
@@ -457,28 +463,28 @@
? disasm_std_operand(stmt, 1, 1);
? break;
? case 0x0D6:
- stmt->u.insn.name = "@D6"; /* FIXME */
+ stmt->u.insn.name = "jdn";
? stmt->u.insn.labelref_operand = 2;
? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
? disasm_std_operand(stmt, 0, 0);
? disasm_std_operand(stmt, 1, 1);
? break;
? case (0x0D6 | 0x1):
- stmt->u.insn.name = "@D7"; /* FIXME */
+ stmt->u.insn.name = "jdpz";
? stmt->u.insn.labelref_operand = 2;
? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
? disasm_std_operand(stmt, 0, 0);
? disasm_std_operand(stmt, 1, 1);
? break;
? case 0x0D8:
- stmt->u.insn.name = "@D8"; /* FIXME */
+ stmt->u.insn.name = "jdp";
? stmt->u.insn.labelref_operand = 2;
? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
? disasm_std_operand(stmt, 0, 0);
? disasm_std_operand(stmt, 1, 1);
? break;
? case (0x0D8 | 0x1):
- stmt->u.insn.name = "@D9"; /* FIXME */
+ stmt->u.insn.name = "jdnz";
? stmt->u.insn.labelref_operand = 2;
? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
? disasm_std_operand(stmt, 0, 0);

#1 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 10 lines · Francesco Gringoli

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Quoted 8 lines

Regards,
-Francesco

-------------=--------------
Description of the new instructions

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

I'd suggest following the x86 convention, and calling it "jl".

Quoted 4 lines

Opcode 0x0D6|1: jumps if the difference between op1 and op2 is positive or null.
Suggested name "jdpz" (jump if difference is positive or zero).

Again, "jge" is a more familiar name.

Quoted 3 lines

Opcode 0x0D8: jumps if the difference between op1 and op2 is positive. Suggested name "jdp" (jump if difference is positive).

Ditto, "jg".

Quoted 4 lines

Opcode 0x0D8|1: jumps if the difference between op1 and op2 is negative or null.
Suggested name "jdnz" (jump if difference is negative or zero).

Ditto, "jle".

Quoted 274 lines

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).
This works on CPUs running ucode11. I have tested it on CPUs running ucode5 and op3 is not assigned.

-------------=--------------
The following changes are made to b43-tools

1) b43-asm assembles new instructions jdn, jdnz, jdp, jdpz, mul;
2) b43-dasm disassembles opcodes 0xD6, 0xD7, 0xD8, 0xD9, 0x101.

Index: assembler/main.c
===================================================================

main.c ? ?2011-09-10 20:22:52.000000000 +0200 renamed from main.c ? ? ? 2011-08-21 14:16:33.000000000 +0200 +3 -0
@@ -737,6 +737,9 @@
 ? ? ? ? unsigned int opcode;
 
 ? ? ? ? switch (insn->op) {
+ ? ? ? ?case OP_MUL:
+ ? ? ? ? ? ? ? ?do_assemble_insn(ctx, insn, 0x101);
+ ? ? ? ? ? ? ? ?break;

? ? ? ? case OP_ADD:
? ? ? ? ? ? ? ? do_assemble_insn(ctx, insn, 0x1C0); ? ? ? ? ? ? ? ? break;

main.c ? ?2011-09-10 20:22:52.000000000 +0200 renamed from main.c ? ? ? 2011-08-21 14:16:33.000000000 +0200 +16 -0
@@ -855,6 +858,22 @@
 ? ? ? ? ? ? ? ? out = do_assemble_insn(ctx, insn, 0x0DC | 0x1);
 ? ? ? ? ? ? ? ? out->is_jump_insn = 1;
 ? ? ? ? ? ? ? ? break;
+ ? ? ? ?case OP_JDN:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D6);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDPZ:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D6 | 0x1);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDP:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D8);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;
+ ? ? ? ?case OP_JDNZ:
+ ? ? ? ? ? ? ? ?out = do_assemble_insn(ctx, insn, 0x0D8 | 0x1);
+ ? ? ? ? ? ? ? ?out->is_jump_insn = 1;
+ ? ? ? ? ? ? ? ?break;

? ? ? ? case OP_JZX:
? ? ? ? ? ? ? ? opcode = merge_ext_into_opcode(ctx, 0x400, insn); ? ? ? ? ? ? ? ? out = do_assemble_insn(ctx, insn, opcode);
Index: assembler/parser.y
===================================================================

parser.y ?2011-09-10 20:26:25.000000000 +0200 renamed from parser.y ? ? 2011-08-21 14:16:33.000000000 +0200 +0 -0
@@ -43,7 +43,7 @@
 

?%token EQUAL NOT_EQUAL LOGICAL_OR LOGICAL_AND PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT

-%token OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE
+%token OP_MUL OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE

?%token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32 IVAL_TRAM

parser.y ?2011-09-10 20:26:25.000000000 +0200 renamed from parser.y ? ? 2011-08-21 14:16:33.000000000 +0200 +7 -0
@@ -176,6 +176,13 @@
 ? ? ? ? ? ? ? ? ? ? ? ? s->u.label = $1;
 ? ? ? ? ? ? ? ? ? ? ? ? $$ = s;
 ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_mul {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct
 statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? | insn_add {

? ? ? ? ? ? ? ? ? ? ? ? struct statement *s = xmalloc(sizeof(struct statement));
? ? ? ? ? ? ? ? ? ? ? ? INIT_LIST_HEAD(&s->list);

parser.y ?2011-09-10 20:26:25.000000000 +0200 renamed from parser.y ? ? 2011-08-21 14:16:33.000000000 +0200 +23 -0
@@ -393,6 +400,34 @@
 ? ? ? ? ? ? ? ? ? ? ? ? s->u.insn = $1;
 ? ? ? ? ? ? ? ? ? ? ? ? $$ = s;
 ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdn {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct
 statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdpz {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct
 statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdp {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct
 statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ?| insn_jdnz {
+ ? ? ? ? ? ? ? ? ? ? ? ?struct statement *s = xmalloc(sizeof(struct

statement));
+ ? ? ? ? ? ? ? ? ? ? ? ?INIT_LIST_HEAD(&s->list);
+ ? ? ? ? ? ? ? ? ? ? ? ?s->type = STMT_INSN;
+ ? ? ? ? ? ? ? ? ? ? ? ?s->u.insn = $1;
+ ? ? ? ? ? ? ? ? ? ? ? ?$$ = s;
+ ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? | insn_jl {
? ? ? ? ? ? ? ? ? ? ? ? struct statement *s = xmalloc(sizeof(struct statement));
? ? ? ? ? ? ? ? ? ? ? ? INIT_LIST_HEAD(&s->list);

parser.y ?2011-09-10 20:26:25.000000000 +0200 renamed from parser.y ? ? 2011-08-21 14:16:33.000000000 +0200 +9 -0
@@ -591,6 +626,15 @@
 ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? ;
 
+/* multiply */
+insn_mul ? ? ? : OP_MUL operlist_3 {
+ ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct
 instruction));
+ ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_MUL;
+ ? ? ? ? ? ? ? ? ? ? ? insn->operands = $2;
+ ? ? ? ? ? ? ? ? ? ? ? $$ = insn;
+ ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ;
+

?/* add */
?insn_add ? ? ? : OP_ADD operlist_3 {
? ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct instruction));

parser.y ?2011-09-10 20:26:25.000000000 +0200 renamed from parser.y ? ? 2011-08-21 14:16:33.000000000 +0200 +26 -0
@@ -897,6 +941,38 @@
 ? ? ? ? ? ? ? ? ?}
 ? ? ? ? ? ? ? ? ;
 
+insn_jdn ? ? ? : OP_JDN operlist_3 {
+ ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct
 instruction));
+ ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_JDN;
+ ? ? ? ? ? ? ? ? ? ? ? insn->operands = $2;
+ ? ? ? ? ? ? ? ? ? ? ? $$ = insn;
+ ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ;
+
+insn_jdpz ? ? ?: OP_JDPZ operlist_3 {
+ ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct
 instruction));
+ ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_JDPZ;
+ ? ? ? ? ? ? ? ? ? ? ? insn->operands = $2;
+ ? ? ? ? ? ? ? ? ? ? ? $$ = insn;
+ ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ;
+
+insn_jdp ? ? ? : OP_JDP operlist_3 {
+ ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct
 instruction));
+ ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_JDP;
+ ? ? ? ? ? ? ? ? ? ? ? insn->operands = $2;
+ ? ? ? ? ? ? ? ? ? ? ? $$ = insn;
+ ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ;
+
+insn_jdnz ? ? ?: OP_JDNZ operlist_3 {
+ ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct

instruction));
+ ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_JDNZ;
+ ? ? ? ? ? ? ? ? ? ? ? insn->operands = $2;
+ ? ? ? ? ? ? ? ? ? ? ? $$ = insn;
+ ? ? ? ? ? ? ? ?}
+ ? ? ? ? ? ? ? ;
+
?insn_jext ? ? ?: OP_JEXT external_jump_operands {
? ? ? ? ? ? ? ? ? ? ? ? struct instruction *insn = xmalloc(sizeof(struct instruction));
? ? ? ? ? ? ? ? ? ? ? ? insn->op = OP_JEXT;
Index: assembler/scanner.l
===================================================================

scanner.l 2011-09-10 20:27:08.000000000 +0200 renamed from scanner.l ? ?2011-08-21 14:16:33.000000000 +0200 +6 -0
@@ -82,6 +82,8 @@
 ?\<\< ? ? ? ? ? ? ? ? ? { update_lineinfo(); return LEFTSHIFT; }
 ?\>\> ? ? ? ? ? ? ? ? ? { update_lineinfo(); return RIGHTSHIFT; }
 
+mul ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_MUL; }
+
 ?add ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_ADD; }
 ?add\. ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_ADDSC; }
 ?addc ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_ADDC; }
@@ -120,6 +122,10 @@
 ?jge ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_JGE; }
 ?jg ? ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_JG; }
 ?jle ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_JLE; }
+jdn ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_JDN; }
+jdpz ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_JDPZ; }
+jdp ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_JDP; }
+jdnz ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_JDNZ; }
 ?jzx ? ? ? ? ? ? ? ? ? ?{ update_lineinfo(); return OP_JZX; }
 ?jnzx ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_JNZX; }
 ?jext ? ? ? ? ? ? ? ? ? { update_lineinfo(); return OP_JEXT; }

Index: disassembler/main.c
===================================================================

main.c 2011-09-11 17:43:25.000000000 +0200 renamed from main.c ? ?2011-08-21 14:16:33.000000000 +0200 +6 -0
@@ -284,6 +284,12 @@
 ? ? ? ? struct bin_instruction *bin = stmt->u.insn.bin;
 
 ? ? ? ? switch (bin->opcode) {
+ ? ? ? case 0x101:
+ ? ? ? ? ? ? ? stmt->u.insn.name = "mul";
+ ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 1, 1);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 2, 2);
+ ? ? ? ? ? ? ? break;

? ? ? ? case 0x1C0:
? ? ? ? ? ? ? ? stmt->u.insn.name = "add";
? ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);

main.c 2011-09-11 17:43:25.000000000 +0200 renamed from main.c ? ?2011-08-21 14:16:33.000000000 +0200 +0 -0
@@ -457,28 +463,28 @@
 ? ? ? ? ? ? ? ? disasm_std_operand(stmt, 1, 1);
 ? ? ? ? ? ? ? ? break;

? ? ? ? case 0x0D6:
- ? ? ? ? ? ? ? stmt->u.insn.name = "@D6"; /* FIXME */
+ ? ? ? ? ? ? ? stmt->u.insn.name = "jdn";
? ? ? ? ? ? ? ? stmt->u.insn.labelref_operand = 2;
? ? ? ? ? ? ? ? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; ? ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);
? ? ? ? ? ? ? ? disasm_std_operand(stmt, 1, 1);
? ? ? ? ? ? ? ? break;
? ? ? ? case (0x0D6 | 0x1):
- ? ? ? ? ? ? ? stmt->u.insn.name = "@D7"; /* FIXME */
+ ? ? ? ? ? ? ? stmt->u.insn.name = "jdpz";
? ? ? ? ? ? ? ? stmt->u.insn.labelref_operand = 2;
? ? ? ? ? ? ? ? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; ? ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);
? ? ? ? ? ? ? ? disasm_std_operand(stmt, 1, 1);
? ? ? ? ? ? ? ? break;
? ? ? ? case 0x0D8:
- ? ? ? ? ? ? ? stmt->u.insn.name = "@D8"; /* FIXME */
+ ? ? ? ? ? ? ? stmt->u.insn.name = "jdp";
? ? ? ? ? ? ? ? stmt->u.insn.labelref_operand = 2;
? ? ? ? ? ? ? ? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; ? ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);
? ? ? ? ? ? ? ? disasm_std_operand(stmt, 1, 1);
? ? ? ? ? ? ? ? break;
? ? ? ? case (0x0D8 | 0x1):
- ? ? ? ? ? ? ? stmt->u.insn.name = "@D9"; /* FIXME */
+ ? ? ? ? ? ? ? stmt->u.insn.name = "jdnz";
? ? ? ? ? ? ? ? stmt->u.insn.labelref_operand = 2;
? ? ? ? ? ? ? ? stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; ? ? ? ? ? ? ? ? disasm_std_operand(stmt, 0, 0);
_______________________________________________
b43-dev mailing list
b43-dev at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/b43-dev

Signature · 1 line
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
#2 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 15 lines · On Mon, 12 Sep 2011 11:12:46 +0200 G?bor Stefanik <[email protected]>…
Quoted 13 lines · Francesco Gringoli

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Regards,
-Francesco

Quoted 7 lines
Quoted 5 lines

-------------=--------------
Description of the new instructions

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

I'd suggest following the x86 convention, and calling it "jl".

Well, no. We already have a jump-if-less.
That reminds me that I already looked into these new instructions once and they seemed quite strange to me.
Francesco, are you really sure your analysis on the instructions is correct? My _guess_ was that they don't work on two's complement. But that was only a guess and I didn't continue research on that.

Signature · 1 line
Greetings, Michael.
#3 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 21 lines · Michael B?sch
Quoted 18 lines · On Mon, 12 Sep 2011 11:12:46 +0200 G?bor Stefanik <[email protected]>…
Quoted 16 lines · Francesco Gringoli

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Regards,
-Francesco

-------------=--------------
Description of the new instructions

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

I'd suggest following the x86 convention, and calling it "jl".

Well, no. We already have a jump-if-less.

Yes, Michael is right. These instructions behave differently.

Quoted 3 lines

That reminds me that I already looked into these new instructions once and they seemed quite strange to me.
Francesco, are you really sure your analysis on the instructions is correct?

Yes, of course I didn't did an exhaustive search trying all the possible values because it would take ages but I implemented a random number generator and tested millions of different cases. I carefully checked also the boundaries (when the difference between the two registers is either zero or 0x8000 or 0x7ffff).

To make it clear the test for jdn proved that

	jdn	r60, r61, target;

is equivalent to

	sub	r60, r61, r62;
	jls	r62, 0, target;

no matter if the carry register is set or not and we are receiving or transmitting something. It was a surprise for me because I was convinced that

if a < b

is equivalent to

if a - b < 0

but trying on a = 0x8000 and b = 0x7fff helped me understanding. a - b = 0x8000 + 2'(0x7fff) = 0x0001 > 0. While 0x8000 < 0x7fff.

Quoted 2 lines

My _guess_ was that they don't work on two's complement. But that was only a guess and I didn't continue research on that.

Well, the subtraction is computed adding the two's complement of b to a, and then the results is checked following a two's complement check over the positiveness of the result.

Regards,
-Francesco

Quoted 3 lines
Signature · 2 lines
-- 
Greetings, Michael.
#4 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 1 line · On Mon, 12 Sep 2011 12:09:01 +0200 francesco.gringoli at ing.unibs.it wrote:

but trying on a = 0x8000 and b = 0x7fff helped me understanding. a - b = 0x8000 + 2'(0x7fff) = 0x0001 > 0. While 0x8000 < 0x7fff.

I don't get it.
Can you write simple pseudocode for your instruction? For example, for jls, we have this pseudocode:

if (xxx < yyy)
pc := jjj
(where xxx and yyy are two's complement)

What does jdX do in C-pseudocode?

http://bcm-v4.sipsolutions.net/802.11/Microcode

Signature · 1 line
Greetings, Michael.
#5 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 7 lines · Michael B?sch
Quoted 1 line · On Mon, 12 Sep 2011 12:09:01 +0200 francesco.gringoli at ing.unibs.it wrote:

but trying on a = 0x8000 and b = 0x7fff helped me understanding. a - b = 0x8000 + 2'(0x7fff) = 0x0001 > 0. While 0x8000 < 0x7fff.

I don't get it.
Can you write simple pseudocode for your instruction?

Will try for jdn.

Quoted 6 lines

For example, for jls, we have this pseudocode:

if (xxx < yyy)
pc := jjj
(where xxx and yyy are two's complement)

** jump if difference is negative

0d6 xxx yyy jjj

if ( xxx - yyy < 0 )
pc := jjj

C-pseudocode for jdn

	short c = xxx - yyy;
	if ( c < 0 )
		goto jjj;

Pay attention: it's not equivalent to

	if( xxx - yyy < 0 )
		goto jjj;

Try this simple code:

int main()

{
	short a = 0x8000;
	short b = 0x7fff;
	short c = a - b;
	printf("%d <=> %d\n", a < b, c < 0);
}

I ' ' think ' ' these instructions are useful and ' ' someone ' ' could use them to check time elapsing in a more efficient way (single instruction rather than a couple.

Regards,
-Francesco

Quoted 6 lines

What does jdX do in C-pseudocode?

http://bcm-v4.sipsolutions.net/802.11/Microcode

Signature · 1 line
Greetings, Michael.
#6 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 22 lines · On Mon, 12 Sep 2011 12:58:52 +0200 francesco.gringoli at ing.unibs.it wrote:
Quoted 7 lines · Michael B?sch
Quoted 1 line · On Mon, 12 Sep 2011 12:09:01 +0200 francesco.gringoli at ing.unibs.it wrote:

but trying on a = 0x8000 and b = 0x7fff helped me understanding. a - b = 0x8000 + 2'(0x7fff) = 0x0001 > 0. While 0x8000 < 0x7fff.

I don't get it.
Can you write simple pseudocode for your instruction?

Will try for jdn.

Quoted 6 lines

For example, for jls, we have this pseudocode:

if (xxx < yyy)
pc := jjj
(where xxx and yyy are two's complement)

** jump if difference is negative

0d6 xxx yyy jjj

Quoted 8 lines

if ( xxx - yyy < 0 )
pc := jjj

C-pseudocode for jdn

	short c = xxx - yyy;
	if ( c < 0 )
		goto jjj;

Ok. So the existing signed-compare jumps look at the carry of the subtraction operation, but the new jdX instructions look at bit 0x8000 of the subtraction result. (if set -> negative, otherwise positive). jdX ignores the carry.

Did I get it now?

Signature · 1 line
Greetings, Michael.
#7 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 30 lines · Michael B?sch
Quoted 27 lines · On Mon, 12 Sep 2011 12:58:52 +0200 francesco.gringoli at ing.unibs.it wrote:
Quoted 7 lines · Michael B?sch
Quoted 1 line · On Mon, 12 Sep 2011 12:09:01 +0200 francesco.gringoli at ing.unibs.it wrote:

but trying on a = 0x8000 and b = 0x7fff helped me understanding. a - b = 0x8000 + 2'(0x7fff) = 0x0001 > 0. While 0x8000 < 0x7fff.

I don't get it.
Can you write simple pseudocode for your instruction?

Will try for jdn.

Quoted 6 lines

For example, for jls, we have this pseudocode:

if (xxx < yyy)
pc := jjj
(where xxx and yyy are two's complement)

** jump if difference is negative

0d6 xxx yyy jjj

if ( xxx - yyy < 0 )
pc := jjj

C-pseudocode for jdn

Quoted 7 lines
Quoted 3 lines
	short c = xxx - yyy;
	if ( c < 0 )
		goto jjj;

Ok. So the existing signed-compare jumps look at the carry of the subtraction operation, but the new jdX instructions look at bit 0x8000 of the subtraction result. (if set -> negative, otherwise positive). jdX ignores the carry.

Exactly. For instance for jdn we have

0d6 xxx yyy jjj

	tmp := xxx - yyy;
	if( tmp & 0x8000 )
		pc := jjj

	or alternatively

	tmp := xxx - yyy;
	if( tmp < 0 )
		pc := jjj

Tested both in the firmware and they are the same.

Do you agree with those names?

Thanks,
-Francesco

#8 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 1 line · On Mon, 12 Sep 2011 15:16:40 +0200 francesco.gringoli at ing.unibs.it wrote:

Do you agree with those names?

Yes I do. I will also add it to the documentation wiki.

Signature · 1 line
Greetings, Michael.
#9 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

In reply to Francesco Gringoli
Quoted 35 lines · On Mon, 12 Sep 2011 10:50:16 +0200 (CEST) Francesco Gringoli…

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Regards,
-Francesco

-------------=--------------
Description of the new instructions

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

Opcode 0x0D6|1: jumps if the difference between op1 and op2 is positive or null.
Suggested name "jdpz" (jump if difference is positive or zero).

Opcode 0x0D8: jumps if the difference between op1 and op2 is positive. Suggested name "jdp" (jump if difference is positive).

Opcode 0x0D8|1: jumps if the difference between op1 and op2 is negative or null.
Suggested name "jdnz" (jump if difference is negative or zero).

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).
This works on CPUs running ucode11. I have tested it on CPUs running ucode5 and op3 is not assigned.

Quoted 5 lines

-------------=--------------
The following changes are made to b43-tools

1) b43-asm assembles new instructions jdn, jdnz, jdp, jdpz, mul;
2) b43-dasm disassembles opcodes 0xD6, 0xD7, 0xD8, 0xD9, 0x101.

Thanks a lot. That looks pretty cool. Could you also add simple testcases to the test.asm file? That file contains basic tests for all instructions and at the end also tests for fixed bugs or special features.

Did you test the jump insns on r5?
And we should probably add a comment which cores support mul (most likely >=r11).

main.c

Quoted 12 lines
main.c +0 -0
@@ -284,6 +284,12 @@
 ?	struct bin_instruction *bin = stmt->u.insn.bin;

?
? switch (bin->opcode) {

main.c +6 -0
+	case 0x101:
+		stmt->u.insn.name = "mul";
+		disasm_std_operand(stmt, 0, 0);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 1, 1);
+ ? ? ? ? ? ? ? ?disasm_std_operand(stmt, 2, 2);
+		break;

There's some whitespace damage here.

Signature · 1 line
Greetings, Michael.
#10 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 41 lines · Michael B?sch
Quoted 38 lines · On Mon, 12 Sep 2011 10:50:16 +0200 (CEST) Francesco Gringoli…

Hi Larry and Michael,

I did some testing with the firmware and discovered the meaning of a few instructions that are currently marked either as "unknown jump" on the bcm-specs site or do not appear at all. I chose some names but maybe you have better ideas regard them.

Here is a brief description of the instructions I'm talking about and a set of patches for b43-tools to enable proper dis/assembly.

Regards,
-Francesco

-------------=--------------
Description of the new instructions

Opcode 0x0D6: jumps if the difference between op1 and op2 is negative. Suggested name "jdn" (jump if difference is negative).

Opcode 0x0D6|1: jumps if the difference between op1 and op2 is positive or null.
Suggested name "jdpz" (jump if difference is positive or zero).

Opcode 0x0D8: jumps if the difference between op1 and op2 is positive. Suggested name "jdp" (jump if difference is positive).

Opcode 0x0D8|1: jumps if the difference between op1 and op2 is negative or null.
Suggested name "jdnz" (jump if difference is negative or zero).

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).
This works on CPUs running ucode11. I have tested it on CPUs running ucode5 and op3 is not assigned.

-------------=--------------
The following changes are made to b43-tools

Quoted 6 lines
Quoted 2 lines

1) b43-asm assembles new instructions jdn, jdnz, jdp, jdpz, mul;
2) b43-dasm disassembles opcodes 0xD6, 0xD7, 0xD8, 0xD9, 0x101.

Thanks a lot. That looks pretty cool. Could you also add simple testcases to the test.asm file? That file contains basic tests for all instructions and at the end also tests for fixed bugs or special features.

Sorry, I didn't know about it :-) . Yes, I will add with short descriptions at the end of each line.

Quoted 2 lines

Did you test the jump insns on r5?

Yes, they all (the jumps) work on r5.

The mul instruction instead works on r11 and does nothing on r5. BTW I don't know if it exists one instruction that assigns the lower 16 bits of the result but I'm sure it's not 0x100 which seems to do the same as 0x101 (the mul). I added 0x101 <=> mul and not 0x100 because 0x100 was never used anywhere.

Quoted 1 line

And we should probably add a comment which cores support mul (most likely >=r11).

Ok, I will add in test.asm.

Quoted 6 lines
Quoted 6 lines
main.c +0 -0
@@ -284,6 +284,12 @@
 	struct bin_instruction *bin = stmt->u.insn.bin;
 
Quoted 9 lines

main.c line 292

Quoted 7 lines
main.c +6 -0
 	switch (bin->opcode) {
+	case 0x101:
+		stmt->u.insn.name = "mul";
+		disasm_std_operand(stmt, 0, 0);
+                disasm_std_operand(stmt, 1, 1);
+                disasm_std_operand(stmt, 2, 2);
+		break;

There's some whitespace damage here.

Sorry, I will resend.

Regards,
-Francesco

Quoted 3 lines
Signature · 2 lines
-- 
Greetings, Michael.
#11 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 2 lines · On Mon, 12 Sep 2011 11:56:20 +0200 francesco.gringoli at ing.unibs.it wrote:
Quoted 1 line

Did you test the jump insns on r5?

Yes, they all (the jumps) work on r5.

Did you also create a truth table for these new jump instructions?
I once did this and there was some weirdness in the extrema (near zero, s16 max or u16 max). I don't find my stuff right now, though. I probably deleted it.

My issue with this is that we already have all of those jump if negative/positive, etc... instructions, so there must be something special with those new insns.

Signature · 1 line
Greetings, Michael.
#12 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

In reply to Francesco Gringoli
Quoted 2 lines · On Mon, 12 Sep 2011 10:50:16 +0200 (CEST) Francesco Gringoli…

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).

So this means the lower 16 bits are discarded? Or where are they put? My guess would be that there's also an instruction that multiplies op1 with op2 and puts the lower 16 bits into op3.
What about opcode 0x100? Are you really sure it does the same as 0x101?

Signature · 1 line
Greetings, Michael.
#13 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 7 lines · Michael B?sch
Quoted 2 lines · On Mon, 12 Sep 2011 10:50:16 +0200 (CEST) Francesco Gringoli…

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).

So this means the lower 16 bits are discarded? Or where are they put?

It seems so. Neither the first or the second operand are modified unfortunately. I tried

	mul	r60, r61, r62;

and we have

	r62 := (r60 * r61) >> 16;

Checked r63 (I thought maybe one register close above to the third operand can be assigned the least significant bits) and it does not change.

Also tried

	mul	r60, r61, r63;

and r62 is not assigned (close below the third operand).

Quoted 2 lines

My guess would be that there's also an instruction that multiplies op1 with op2 and puts the lower 16 bits into op3.

In fact!

Quoted 1 line

What about opcode 0x100? Are you really sure it does the same as 0x101?

@100 and @101 does apparently the same; indeed result does not depend on the carry and it does not set it.

Maybe @100 and @101 does something different but I should investigate.

Thanks,
-Francesco

Quoted 4 lines
Signature · 2 lines
-- 
Greetings, Michael.
#14 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

In reply to Michael Büsch
Quoted 7 lines · Michael B?sch
Quoted 2 lines · On Mon, 12 Sep 2011 10:50:16 +0200 (CEST) Francesco Gringoli…

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).

So this means the lower 16 bits are discarded? Or where are they put?

Aha! easy as candy! They are put in spr06d.

Still @100 and @101 does the same...

-Francesco

Quoted 6 lines

My guess would be that there's also an instruction that multiplies op1 with op2 and puts the lower 16 bits into op3.
What about opcode 0x100? Are you really sure it does the same as 0x101?

Signature · 1 line
Greetings, Michael.
#15 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 5 lines · On Mon, 12 Sep 2011 16:04:14 +0200 francesco.gringoli at ing.unibs.it wrote:
Quoted 4 lines
Quoted 2 lines

Opcode 0x101: multiply op1 and op2 and store upper 16 bits in op3. Suggested name "mul" (multiply).

So this means the lower 16 bits are discarded? Or where are they put?

Aha! easy as candy! They are put in spr06d.

Ok. That's the second "PSM" register, which kind of makes sense. (The first "PSM" register is already used by the "PSM conditions")

So yeah, in that case I'm also OK with this instruction.

I will also add this to the documentation.

Signature · 1 line
Greetings, Michael.
#16 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

In reply to Francesco Gringoli

Francesco, did you also take a look at the new rev 15+ subroutine call mechanism?
http://bcm-v4.sipsolutions.net/802.11/Microcode#subroutines_.28rev_15.2B-_cores_only.29

My guess is that it stores the call stack somewhere in SHM or probably some new dedicated memory. I did not try anything of that on a device, yet, but from looking at the disassembly it's pretty obvious that this is a call/ret mechanism. What I don't see from the code is where the stack is put, though. If it's put into SHM, that should be easy to spot.

Signature · 1 line
Greetings, Michael.
#17 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 2 lines · Michael B?sch

Francesco, did you also take a look at the new rev 15+ subroutine call mechanism?
http://bcm-v4.sipsolutions.net/802.11/Microcode#subroutines_.28rev_15.2B-_cores_only.29

Not yet. I just received a couple of cards using ucode16 but I would like to first finish final firmwares for ucode5 and ucode11.

BTW starting with ucode11 there are a couple of new jumps, opcodes 0x70 and 0x70|1. If I'm not wrong they are not documented BUT they behave exactly as je and jne. Did you ever take a look at them? They seem duplicate opcodes but it's weird that they duplicate wires on the chips.

Thanks,
-Francesco

#18 lore raw

PATCH 1/1 b43-asm, b43-dasm: Add 5 new instructions.

Quoted 1 line · On Mon, 12 Sep 2011 16:44:48 +0200 francesco.gringoli at ing.unibs.it wrote:

BTW starting with ucode11 there are a couple of new jumps, opcodes 0x70 and 0x70|1. If I'm not wrong they are not documented BUT they behave exactly as je and jne. Did you ever take a look at them? They seem duplicate opcodes but it's weird that they duplicate wires on the chips.

I didn't check that, yet.
Maybe they are faster, but must not be used under certain conditions. Or maybe they don't have the "ret problem". These are pure guesses, though...

Signature · 1 line
Greetings, Michael.