X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fmain.c;h=255cabc88c74b6966d0c0a4262e374d2048cdf14;hb=e882e360ba16d2eed103adffdd1809076ee98017;hp=774f8f956dc5ad40ded7e40b7ba49079a43f4072;hpb=f9562faebded909074edeff5269cd7f3e122a012;p=b43-tools.git diff --git a/assembler/main.c b/assembler/main.c index 774f8f9..255cabc 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -571,19 +571,20 @@ static void emulate_jmp_insn(struct assembler_context *ctx, { struct instruction em_insn; struct operlist em_ol; - struct operand em_op; - struct immediate em_imm; - - /* This is a pseudo-OP. We emulate it by JE */ - - em_insn.op = OP_JE; - em_imm.imm = 1; - em_op.type = OPER_IMM; - em_op.u.imm = &em_imm; - em_ol.oper[0] = &em_op; - em_ol.oper[1] = &em_op; - em_ol.oper[2] = insn->operands->oper[0]; + struct immediate em_condition; + struct operand em_cond_op; + + /* This is a pseudo-OP. We emulate it with + * JEXT 0x7F, target */ + + em_insn.op = OP_JEXT; + em_condition.imm = 0x7F; /* Ext cond: Always true */ + em_cond_op.type = OPER_IMM; + em_cond_op.u.imm = &em_condition; + em_ol.oper[0] = &em_cond_op; + em_ol.oper[1] = insn->operands->oper[0]; /* Target */ em_insn.operands = &em_ol; + assemble_instruction(ctx, &em_insn); /* recurse */ } @@ -816,13 +817,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); @@ -1121,6 +1125,12 @@ static void emit_code(struct assembler_context *ctx) break; } } + + if (arg_print_sizes) { + printf("%s: text = %u instructions (%u bytes)\n", + fn, insn_count, insn_count * sizeof(uint64_t)); + } + fclose(fd); free(fn); }