X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fmain.c;h=a62a15eca52028a6dc2e0efcfde6ffc659ae9fe2;hb=HEAD;hp=461b0d8126cca3764300bf393fd1ce170122f253;hpb=4366b5ddfc844ad72d9fd8e62418307c70407154;p=b43-tools.git diff --git a/assembler/main.c b/assembler/main.c index 461b0d8..a62a15e 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 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 @@ -429,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; @@ -482,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) @@ -716,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; @@ -834,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); @@ -855,22 +895,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: @@ -994,7 +1036,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. */ @@ -1081,7 +1123,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) { @@ -1093,7 +1135,7 @@ static void emit_code(struct assembler_context *ctx) } } - switch (output_format) { + switch (cmdargs.outformat) { case FMT_RAW_LE32: case FMT_RAW_BE32: /* Nothing */ @@ -1129,7 +1171,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, @@ -1156,7 +1198,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) | @@ -1192,7 +1234,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))); @@ -1218,7 +1260,7 @@ static void initialize(void) { INIT_LIST_HEAD(&infile.sl); INIT_LIST_HEAD(&infile.ivals); -#ifdef YYDEBUG +#if YYDEBUG if (IS_INSANE_DEBUG) yydebug = 1; else