From: Francesco Gringoli Date: Mon, 12 Sep 2011 17:49:37 +0000 (+0200) Subject: b43-asm, b43-dasm: Add 5 new instructions. X-Git-Tag: b43-fwcutter-016~6 X-Git-Url: https://jxself.org/git/?p=b43-tools.git;a=commitdiff_plain;h=a392db777966d9e35be7c95590cdb24aa7f41ec1 b43-asm, b43-dasm: Add 5 new instructions. The following changes are made to b43-tools 1) b43-asm assembles new instructions jdn, jdnz, jdp, jdpz, mul; 2) b43-asm new instructions added to test.asm source; 3) b43-dasm disassembles opcodes 0xD6, 0xD7, 0xD8, 0xD9, 0x101. Signed-off-by: Francesco Gringoli Signed-off-by: Michael Buesch --- diff --git a/assembler/main.c b/assembler/main.c index f4ee51d..afca996 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -737,6 +737,9 @@ static void assemble_instruction(struct assembler_context *ctx, 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 @@ static void assemble_instruction(struct assembler_context *ctx, 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); diff --git a/assembler/parser.y b/assembler/parser.y index e102911..317af05 100644 --- a/assembler/parser.y +++ b/assembler/parser.y @@ -43,7 +43,7 @@ extern struct initvals_sect *cur_initvals_sect; %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 @@ statement : asmdir { 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 @@ statement : asmdir { 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 @@ label : LABEL { } ; +/* 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_jnzx : OP_JNZX extended_operlist { } ; +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; diff --git a/assembler/scanner.l b/assembler/scanner.l index 382fe35..dfc63d0 100644 --- a/assembler/scanner.l +++ b/assembler/scanner.l @@ -82,6 +82,8 @@ lr/[0-3] { update_lineinfo(); return LR; } \<\< { 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 @@ jl { update_lineinfo(); return OP_JL; } 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; } diff --git a/assembler/test.asm b/assembler/test.asm index a228d45..cea8724 100644 --- a/assembler/test.asm +++ b/assembler/test.asm @@ -39,6 +39,9 @@ mov (1 + (%assert(1 == ((1 + 2) - 2)))), r0 label: + /* MUL instruction */ + mul r0,r1,r2 /* mul, r2 := msb, spr6d := lsb */ + /* ADD instructions */ add r0,r1,r2 /* add */ add. r0,r1,r2 /* add, set carry */ @@ -89,6 +92,10 @@ testlabel: jge r0,r1,label /* jump if greater or equal */ jg r0,r1,label /* jump if greater */ jle r0,r1,label /* jump if less or equal */ + jdn r0,r1,label /* jump if difference is negative */ + jdpz r0,r1,label /* jump if difference is non negative */ + jdp r0,r1,label /* jump if difference is positive */ + jdnz r0,r1,label /* jump if difference is non positive */ jzx 7,8,r0,r1,label /* Jump if zero after shift and mask */ jnzx 7,8,r0,r1,label /* Jump if nonzero after shift and mask */ diff --git a/disassembler/main.c b/disassembler/main.c index 6cf39b6..d419fee 100644 --- a/disassembler/main.c +++ b/disassembler/main.c @@ -284,6 +284,12 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, 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 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, 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);