X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fmain.c;h=b262276d2ee800305d6a192b42fd1e73b80cfdb3;hb=caac2299fff40df153b35b0d02f5561e207dbdbb;hp=c4cad33827a190228e5adc34f8eb86bd0d9cbab1;hpb=88eca946bfdcb1ec27b2bae849152bc2a7b6872a;p=b43-tools.git diff --git a/assembler/main.c b/assembler/main.c index c4cad33..b262276 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2007 Michael Buesch + * Copyright (C) 2006-2010 Michael Buesch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -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); @@ -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: