assembler: Some r15 fixes
[b43-tools.git] / assembler / main.c
index 255cabc88c74b6966d0c0a4262e374d2048cdf14..309d7c5fed1f95536345efe4f26354d70b97eeb0 100644 (file)
@@ -325,9 +325,21 @@ static unsigned int generate_mem_operand(struct assembler_context *ctx,
        case MEM_DIRECT:
                /* format: 0b0mmm mmmm mmmm */
                off = mem->offset;
-               if (off & ~0x7FF) { //FIXME 4096 words for v15 arch possible?
-                       asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 11 bits)", off);
-                       off &= 0x7FF;
+               switch (ctx->arch) {
+               case 5:
+                       if (off & ~0x7FF) {
+                               asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 11 bits)", off);
+                               off &= 0x7FF;
+                       }
+                       break;
+               case 15:
+                       if (off & ~0xFFF) {
+                               asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 12 bits)", off);
+                               off &= 0xFFF;
+                       }
+                       break;
+               default:
+                       asm_error(ctx, "Internal error: generate_mem_operand invalid arch");
                }
                val |= off;
                break;
@@ -341,8 +353,14 @@ static unsigned int generate_mem_operand(struct assembler_context *ctx,
                        asm_warn(ctx, "INDIRECT memoffset 0x%X too long (> 6 bits)", off);
                        off &= 0x3F;
                }
-               if (reg & ~0x7)
+               if (reg > 6) {
+                       /* Assembler bug. The parser shouldn't pass this value. */
                        asm_error(ctx, "OFFR-nr too big");
+               }
+               if (reg == 6 && ctx->arch == 5) {
+                       asm_warn(ctx, "Using offset register 6. This register is broken "
+                                "on architecture 5 devices. Use off0 to off5 only.");
+               }
                val |= off;
                val |= (reg << 6);
                break;
@@ -823,8 +841,8 @@ static void assemble_instruction(struct assembler_context *ctx,
                        /* 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.");
+                                       asm_warn(ctx, "RET instruction directly after "
+                                                "jump instruction. The hardware won't like this.");
                                }
                                break;
                        }
@@ -1026,21 +1044,17 @@ does_not_exist:
 static void emit_code(struct assembler_context *ctx)
 {
        FILE *fd;
-       char *fn;
-       size_t fn_len;
+       const char *fn;
        struct code_output *c;
        uint64_t code;
        unsigned char outbuf[8];
        unsigned int insn_count = 0;
        struct fw_header hdr;
 
-       fn_len = strlen(outfile_name) + 20;
-       fn = xmalloc(fn_len);
-       snprintf(fn, fn_len, "%s.ucode", outfile_name);
+       fn = outfile_name;
        fd = fopen(fn, "w+");
        if (!fd) {
                fprintf(stderr, "Could not open microcode output file \"%s\"\n", fn);
-               free(fn);
                exit(1);
        }
        if (IS_VERBOSE_DEBUG)
@@ -1128,11 +1142,11 @@ static void emit_code(struct assembler_context *ctx)
 
        if (arg_print_sizes) {
                printf("%s:  text = %u instructions (%u bytes)\n",
-                      fn, insn_count, insn_count * sizeof(uint64_t));
+                      fn, insn_count,
+                      (unsigned int)(insn_count * sizeof(uint64_t)));
        }
 
        fclose(fd);
-       free(fn);
 }
 
 static void assemble(void)