fwcutter/make: Avoid _DEFAULT_SOURCE warning
[b43-tools.git] / assembler / main.c
index 461b0d8126cca3764300bf393fd1ce170122f253..a62a15eca52028a6dc2e0efcfde6ffc659ae9fe2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) 2006-2010  Michael Buesch <mb@bu3sch.de>
+ *   Copyright (C) 2006-2010  Michael Buesch <m@bues.ch>
  *
  *   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