On Mon, Sep 12, 2011 at 10:50 AM, Francesco Gringoli <francesco.gring...@ing.unibs.it> wrote: > 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).
I'd suggest following the x86 convention, and calling it "jl". > > 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. > > Opcode 0x0D8: jumps if the difference between op1 and op2 is positive. > Suggested name "jdp" (jump if difference is positive). Ditto, "jg". > > 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". > > 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. > > Signed-off-by: Francesco Gringoli <francesco.gring...@ing.unibs.it> > > Index: assembler/main.c > =================================================================== > --- assembler.orig/main.c 2011-08-21 14:16:33.000000000 +0200 > +++ assembler/main.c 2011-09-10 20:22:52.000000000 +0200 > @@ -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); > Index: assembler/parser.y > =================================================================== > --- assembler.orig/parser.y 2011-08-21 14:16:33.000000000 +0200 > +++ assembler/parser.y 2011-09-10 20:26:25.000000000 +0200 > @@ -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; > Index: assembler/scanner.l > =================================================================== > --- assembler.orig/scanner.l 2011-08-21 14:16:33.000000000 +0200 > +++ assembler/scanner.l 2011-09-10 20:27:08.000000000 +0200 > @@ -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 > =================================================================== > --- disassembler.orig/main.c 2011-08-21 14:16:33.000000000 +0200 > +++ disassembler/main.c 2011-09-11 17:43:25.000000000 +0200 > @@ -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); > _______________________________________________ > b43-dev mailing list > b43-dev@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/b43-dev > > -- Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-) _______________________________________________ b43-dev mailing list b43-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/b43-dev