diff options
Diffstat (limited to 'gas/config/tc-kvx.c')
-rw-r--r-- | gas/config/tc-kvx.c | 112 |
1 files changed, 51 insertions, 61 deletions
diff --git a/gas/config/tc-kvx.c b/gas/config/tc-kvx.c index 942b1ab..b4ca25c 100644 --- a/gas/config/tc-kvx.c +++ b/gas/config/tc-kvx.c @@ -509,7 +509,7 @@ insert_operand (struct kvxinsn *insn, struct kvx_operand *opdef, { char *ilp_save = input_line_pointer; input_line_pointer = tok->tok; - expressionS exp = { 0 }; + expressionS exp; expression (&exp); input_line_pointer = ilp_save; @@ -700,7 +700,7 @@ assemble_insn (const struct kvxopc * opcode, struct token_list *tok, struct kvxi insn->immx1 = NOIMMX; struct token_list *tok_ = tok; - struct kvx_operand **format = (struct kvx_operand **) opcode->format; + struct kvx_operand *const *format = opcode->format; while (tok_) { @@ -1021,7 +1021,7 @@ kvx_print_insn (struct kvxopc * op ATTRIBUTE_UNUSED) /* This is a hack which works because the Bundling is the same for all cores for now. */ - switch ((int) op->bundling) + switch (op->bundling) { case Bundling_kv3_v1_ALL: insn_type = "ALL "; @@ -1109,7 +1109,7 @@ kvx_reorder_bundle (struct kvxinsn *bundle_insn[], int bundle_insncnt) tag = -1, exu = -1; /* This is a hack. It works because all the Bundling are the same for all cores for now. */ - switch ((int) find_bundling (kvxinsn)) + switch (find_bundling (kvxinsn)) { case Bundling_kv3_v1_ALL: if (bundle_insncnt > 1) @@ -1441,8 +1441,8 @@ kvx_set_cpu (void) static int kvxop_compar (const void *a, const void *b) { - const struct kvxopc *opa = (const struct kvxopc *) a; - const struct kvxopc *opb = (const struct kvxopc *) b; + const struct kvxopc *opa = a; + const struct kvxopc *opb = b; int res = strcmp (opa->as_op, opb->as_op); if (res) @@ -1644,7 +1644,7 @@ md_apply_fix (fixS * fixP, valueT * valueP, segT segmentP ATTRIBUTE_UNUSED) valueT image; arelent *rel; - rel = (arelent *) xmalloc (sizeof (arelent)); + rel = xmalloc (sizeof (arelent)); rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); if (rel->howto == NULL) @@ -2355,16 +2355,11 @@ kvx_endp (int start ATTRIBUTE_UNUSED) if (exp.X_op == O_constant) { S_SET_SIZE (last_proc_sym, exp.X_add_number); - if (symbol_get_obj (last_proc_sym)->size) - { - xfree (symbol_get_obj (last_proc_sym)->size); - symbol_get_obj (last_proc_sym)->size = NULL; - } + symbol_get_obj (last_proc_sym)->size = NULL; } else { - symbol_get_obj (last_proc_sym)->size = - (expressionS *) xmalloc (sizeof (expressionS)); + symbol_get_obj (last_proc_sym)->size = notes_alloc (sizeof (exp)); *symbol_get_obj (last_proc_sym)->size = exp; } @@ -2518,20 +2513,18 @@ kvx_force_reloc_sub_same (fixS * fixP, segT sec) return 1; } -/* Implement HANDLE_ALIGN. */ +/* Pads code section with bundle of nops when possible, 0 if not. */ -static void -kvx_make_nops (char *buf, bfd_vma bytes) +void +kvx_handle_align (fragS *fragP) { - bfd_vma i = 0; - unsigned int j; + if (fragP->fr_type != rs_align_code) + return; static unsigned int nop_single = 0; - if (!nop_single) { - const struct kvxopc *opcode = - (struct kvxopc *) str_hash_find (env.opcode_hash, "nop"); + const struct kvxopc *opcode = str_hash_find (env.opcode_hash, "nop"); if (opcode == NULL) as_fatal @@ -2540,52 +2533,49 @@ kvx_make_nops (char *buf, bfd_vma bytes) nop_single = opcode->codewords[0].opcode; } - /* KVX instructions are always 4-bytes aligned. If we are at a position */ - /* that is not 4 bytes aligned, it means this is not part of an instruction, */ - /* so it is safe to use a zero byte for padding. */ + bfd_signed_vma bytes = (fragP->fr_next->fr_address + - fragP->fr_address - fragP->fr_fix); + if (bytes <= 0) + return; - for (j = bytes % 4; j > 0; j--) - buf[i++] = 0; + char *p = fragP->fr_literal + fragP->fr_fix; - for (j = 0; j < (bytes - i); j += 4) + /* KVX instructions are always 4-bytes aligned. If we are at a + position that is not 4 bytes aligned, it means this is not part + of an instruction, so it is safe to use a zero byte for padding. */ + int fix = bytes & 3; + if (fix != 0) { - unsigned nop = nop_single; - - // nop has bundle end only if #4 nop or last padding nop. - // Sets the parallel bit when neither conditions are matched. - // 4*4 = biggest nop bundle we can get - // 12 = offset when writting the last nop possible in a 4 nops bundle - // bytes-i-4 = offset for the last 4-words in the padding - if (j % (4 * 4) != 12 && j != (bytes - i - 4)) - nop |= PARALLEL_BIT; - - memcpy (buf + i + j, &nop, sizeof (nop)); + memset (p, 0, fix); + p += fix; + bytes -= fix; } -} -/* Pads code section with bundle of nops when possible, 0 if not. */ -void -kvx_handle_align (fragS *fragP) -{ - switch (fragP->fr_type) + /* Output any nops that don't make a full bundle. */ + while (bytes & 15) { - case rs_align_code: - { - bfd_signed_vma bytes = (fragP->fr_next->fr_address - - fragP->fr_address - fragP->fr_fix); - char *p = fragP->fr_literal + fragP->fr_fix; - - if (bytes <= 0) - break; - - /* Insert zeros or nops to get 4 byte alignment. */ - kvx_make_nops (p, bytes); - fragP->fr_fix += bytes; - } - break; + unsigned int nop = nop_single; + bytes -= 4; + if (bytes & 15) + nop |= PARALLEL_BIT; + memcpy (p, &nop, 4); + p += 4; + fix += 4; + } + fragP->fr_fix += fix; - default: - break; + /* Any more are repeated copies of this full bundle of nops. */ + if (bytes) + { + unsigned int nop = nop_single | PARALLEL_BIT; + memcpy (p, &nop, 4); + p += 4; + memcpy (p, &nop, 4); + p += 4; + memcpy (p, &nop, 4); + p += 4; + memcpy (p, &nop_single, 4); + fragP->fr_var = 16; } } /* |