X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fmain.c;h=3f207baf1ed69e412d4f5a6be1c48e05a52c6607;hb=15e6569e86bfc42db9932b3e817161c13d083252;hp=1dac1c7cafa146068c38d027f82f41a1dcaf0a9a;hpb=1c0560b49eb2c403d0d0fa99f789f13f750a40d8;p=b43-tools.git diff --git a/assembler/main.c b/assembler/main.c index 1dac1c7..3f207ba 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -470,6 +470,9 @@ static unsigned int merge_external_jmp_into_opcode(struct assembler_context *ctx unsigned int opbase, struct instruction *insn) { + struct operand *fake; + struct registr *fake_reg; + struct operand *target; struct operlist *ol; unsigned int cond; unsigned int opcode; @@ -480,9 +483,21 @@ static unsigned int merge_external_jmp_into_opcode(struct assembler_context *ctx if (cond & ~0xFF) asm_error(ctx, "External jump condition value too big (> 0xFF)"); opcode |= cond; - ol->oper[0] = ol->oper[1]; - ol->oper[1] = ol->oper[2]; - ol->oper[2] = ol->oper[3]; + target = ol->oper[1]; + memset(ol->oper, 0, sizeof(ol->oper)); + + /* This instruction has two fake r0 operands + * at position 0 and 1. */ + fake = xmalloc(sizeof(*fake)); + fake_reg = xmalloc(sizeof(*fake_reg)); + fake->type = OPER_REG; + fake->u.reg = fake_reg; + fake_reg->type = GPR; + fake_reg->nr = 0; + + ol->oper[0] = fake; + ol->oper[1] = fake; + ol->oper[2] = target; return opcode; } @@ -801,13 +816,16 @@ static void assemble_instruction(struct assembler_context *ctx, do_assemble_insn(ctx, insn, 0x002); break; case OP_RET: - if (!list_empty(&ctx->output)) { - /* Get the previous instruction and check whether it - * is a jump instruction. */ - out = list_entry(ctx->output.prev, struct code_output, list); - if (out->is_jump_insn) { - asm_error(ctx, "RET instruction directly after " - "jump instruction. The hardware won't like this."); + /* Get the previous instruction and check whether it + * is a jump instruction. */ + list_for_each_entry_reverse(out, &ctx->output, list) { + /* Search the last insn. */ + if (out->type == OUT_INSN) { + if (out->is_jump_insn) { + asm_error(ctx, "RET instruction directly after " + "jump instruction. The hardware won't like this."); + } + break; } } do_assemble_insn(ctx, insn, 0x003);