X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fmain.c;h=ad180b274bc8ac2520718a83f7590d5a3b23011b;hb=e21b92e66ad6c143da489331d4d56abfa2092160;hp=10e5cd3c4925234a3c2c84d6c94903a0ccbd291f;hpb=52a2b6fe8fc49b4e4c46d81242ee372089570470;p=b43-tools.git diff --git a/assembler/main.c b/assembler/main.c index 10e5cd3..ad180b2 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -117,6 +117,7 @@ static void eval_directives(struct assembler_context *ctx) struct label *l; int have_start_label = 0; int have_arch = 0; + unsigned int arch_fallback = 0; for_each_statement(ctx, s) { if (s->type == STMT_ASMDIR) { @@ -126,6 +127,17 @@ static void eval_directives(struct assembler_context *ctx) if (have_arch) asm_error(ctx, "Multiple %%arch definitions"); ctx->arch = ad->u.arch; + if (ctx->arch > 5 && ctx->arch < 15) + arch_fallback = 5; + if (ctx->arch > 15) + arch_fallback = 15; + if (arch_fallback) { + asm_warn(ctx, "Using %%arch %d is incorrect. " + "The wireless core revision %d uses the " + "firmware architecture %d. So use %%arch %d", + ctx->arch, ctx->arch, arch_fallback, arch_fallback); + ctx->arch = arch_fallback; + } if (ctx->arch != 5 && ctx->arch != 15) { asm_error(ctx, "Architecture version %u unsupported", ctx->arch); @@ -417,7 +429,7 @@ static struct code_output * do_assemble_insn(struct assembler_context *ctx, struct instruction *insn, unsigned int opcode) { - int i; + unsigned int i; struct operlist *ol; int nr_oper = 0; uint64_t code = 0; @@ -470,6 +482,27 @@ static struct code_output * do_assemble_insn(struct assembler_context *ctx, return out; } +static void do_assemble_ret(struct assembler_context *ctx, + struct instruction *insn, + unsigned int opcode) +{ + struct code_output *out; + + /* 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_warn(ctx, "RET instruction directly after " + "jump instruction. The hardware won't like this."); + } + break; + } + } + do_assemble_insn(ctx, insn, opcode); +} + static unsigned int merge_ext_into_opcode(struct assembler_context *ctx, unsigned int opbase, struct instruction *insn) @@ -843,22 +876,24 @@ static void assemble_instruction(struct assembler_context *ctx, out->is_jump_insn = 1; break; case OP_CALL: + if (ctx->arch != 5) + asm_error(ctx, "'call' instruction is only supported on arch 5"); do_assemble_insn(ctx, insn, 0x002); break; + case OP_CALLS: + if (ctx->arch != 15) + asm_error(ctx, "'calls' instruction is only supported on arch 15"); + do_assemble_insn(ctx, insn, 0x004); + break; case OP_RET: - /* 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_warn(ctx, "RET instruction directly after " - "jump instruction. The hardware won't like this."); - } - break; - } - } - do_assemble_insn(ctx, insn, 0x003); + if (ctx->arch != 5) + asm_error(ctx, "'ret' instruction is only supported on arch 5"); + do_assemble_ret(ctx, insn, 0x003); + break; + case OP_RETS: + if (ctx->arch != 15) + asm_error(ctx, "'rets' instruction is only supported on arch 15"); + do_assemble_insn(ctx, insn, 0x005); break; case OP_TKIPH: case OP_TKIPHS: @@ -982,7 +1017,7 @@ static void resolve_labels(struct assembler_context *ctx) { struct code_output *c; int addr; - int i; + unsigned int i; unsigned int current_address; /* Calculate the absolute addresses for each instruction. */ @@ -1069,7 +1104,7 @@ static void emit_code(struct assembler_context *ctx) exit(1); } if (IS_VERBOSE_DEBUG) - fprintf(stderr, "\nCode:\n"); + printf("\nCode:\n"); list_for_each_entry(c, &ctx->output, list) { switch (c->type) { @@ -1081,7 +1116,7 @@ static void emit_code(struct assembler_context *ctx) } } - switch (output_format) { + switch (cmdargs.outformat) { case FMT_RAW_LE32: case FMT_RAW_BE32: /* Nothing */ @@ -1117,7 +1152,7 @@ static void emit_code(struct assembler_context *ctx) switch (c->type) { case OUT_INSN: if (IS_VERBOSE_DEBUG) { - fprintf(stderr, "%03X %03X,%03X,%03X\n", + printf("%03X %04X,%04X,%04X\n", c->opcode, c->operands[0].u.operand, c->operands[1].u.operand, @@ -1144,7 +1179,7 @@ static void emit_code(struct assembler_context *ctx) ctx->arch); } - switch (output_format) { + switch (cmdargs.outformat) { case FMT_B43: case FMT_RAW_BE32: code = ((code & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) | @@ -1180,7 +1215,7 @@ static void emit_code(struct assembler_context *ctx) } } - if (arg_print_sizes) { + if (cmdargs.print_sizes) { printf("%s: text = %u instructions (%u bytes)\n", fn, insn_count, (unsigned int)(insn_count * sizeof(uint64_t)));