From: Alan Modra Date: Wed, 11 Dec 2019 06:15:14 +0000 (+1030) Subject: Remove more shifts for sign/zero extension X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1d61b032265e69317f42e8019e072506f11890c5;p=binutils-gdb.git Remove more shifts for sign/zero extension cpu/ * epiphany.cpu (f-sdisp11): Don't sign extend with shifts. * lm32.cpu (f-branch, f-vall): Likewise. * m32.cpu (f-lab-8-16): Likewise. opcodes/ * arc-dis.c (BITS): Don't truncate high bits with shifts. * nios2-dis.c (nios2_print_insn_arg): Don't sign extend with shifts. * tic54x-dis.c (print_instruction): Likewise. * tilegx-opc.c (parse_insn_tilegx): Likewise. * tilepro-opc.c (parse_insn_tilepro): Likewise. * visium-dis.c (disassem_class0): Likewise. * pdp11-dis.c (sign_extend): Likewise. (SIGN_BITS): Delete. * epiphany-ibld.c: Regenerate. * lm32-ibld.c: Regenerate. * m32c-ibld.c: Regenerate. --- diff --git a/cpu/ChangeLog b/cpu/ChangeLog index fd26cb78b4b..c5a44ab45f0 100644 --- a/cpu/ChangeLog +++ b/cpu/ChangeLog @@ -1,3 +1,9 @@ +2019-12-11 Alan Modra + + * epiphany.cpu (f-sdisp11): Don't sign extend with shifts. + * lm32.cpu (f-branch, f-vall): Likewise. + * m32.cpu (f-lab-8-16): Likewise. + 2019-12-11 Alan Modra * epiphany.cpu (f-simm8, f-simm24): Use multiply rather than diff --git a/cpu/epiphany.cpu b/cpu/epiphany.cpu index 9f873b38f47..02bce0779d5 100644 --- a/cpu/epiphany.cpu +++ b/cpu/epiphany.cpu @@ -228,10 +228,11 @@ (set (ifield f-disp3) (and SI (ifield f-sdisp11) 7))) (sequence () ;decode (set (ifield f-sdisp11) - (sra SI (sll SI (or SI (sll (ifield f-disp8) 3) - (ifield f-disp3)) - 21) - 21))) + (sub SI (xor (and (or (sll (ifield f-disp8) 3) + (ifield f-disp3)) + #x7ff) + #x400) + #x400))) ) (dnmf f-imm16 "Short immediate for move/add/sub" () UINT (f-imm8 f-imm-27-8) diff --git a/cpu/lm32.cpu b/cpu/lm32.cpu index 83c839f3392..ecd8160816e 100644 --- a/cpu/lm32.cpu +++ b/cpu/lm32.cpu @@ -128,11 +128,15 @@ (df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT ((value pc) (sra SI (sub SI value pc) 2)) - ((value pc) (add SI pc (sra SI (sll SI value 16) 14))) + ((value pc) (add SI pc (sub (xor (sll (and value #xffff) 2) + #x20000) + #x20000))) ) (df f-call "call offset field" (PCREL-ADDR) 25 26 INT ((value pc) (sra SI (sub SI value pc) 2)) - ((value pc) (add SI pc (sra SI (sll SI value 6) 4))) + ((value pc) (add SI pc (sub (xor (sll (and value #x3ffffff) 2) + #x8000000) + #x8000000))) ) diff --git a/cpu/m32c.cpu b/cpu/m32c.cpu index bcc36161f7c..5a38f1bd526 100644 --- a/cpu/m32c.cpu +++ b/cpu/m32c.cpu @@ -956,9 +956,12 @@ ) (df f-lab-8-16 "16 bit pc relative signed offset" (PCREL-ADDR SIGN-OPT all-isas) 8 16 UINT ((value pc) (or SI (sll (and (sub value (add pc 1)) #xff) 8) - (srl (and (sub value (add pc 1)) #xffff) 8))) - ((value pc) (add SI (or (srl (and value #xffff) 8) - (sra (sll (and value #xff) 24) 16)) (add pc 1))) + (srl (and (sub value (add pc 1)) #xff00) 8))) + ((value pc) (add SI (sub (xor (or (srl (and value #xff00) 8) + (sll (and value #xff) 8)) + #x8000) + #x8000) + (add pc 1))) ) (df f-lab-8-24 "24 bit absolute" (all-isas ABS-ADDR) 8 24 UINT ((value pc) (or SI diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 5345dfb2bf7..2a44855e4f7 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,17 @@ +2019-12-11 Alan Modra + + * arc-dis.c (BITS): Don't truncate high bits with shifts. + * nios2-dis.c (nios2_print_insn_arg): Don't sign extend with shifts. + * tic54x-dis.c (print_instruction): Likewise. + * tilegx-opc.c (parse_insn_tilegx): Likewise. + * tilepro-opc.c (parse_insn_tilepro): Likewise. + * visium-dis.c (disassem_class0): Likewise. + * pdp11-dis.c (sign_extend): Likewise. + (SIGN_BITS): Delete. + * epiphany-ibld.c: Regenerate. + * lm32-ibld.c: Regenerate. + * m32c-ibld.c: Regenerate. + 2019-12-11 Alan Modra * ns32k-dis.c (sign_extend): Correct last patch. diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c index a038fa0ca27..a47e81f0a28 100644 --- a/opcodes/arc-dis.c +++ b/opcodes/arc-dis.c @@ -137,8 +137,7 @@ static bfd_boolean print_hex = FALSE; (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \ : bfd_getb32 (buf)) -#define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \ - (s + (sizeof (word) * 8 - 1 - e))) +#define BITS(word,s,e) (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1)) #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31)) /* Functions implementation. */ diff --git a/opcodes/epiphany-ibld.c b/opcodes/epiphany-ibld.c index 6e6fd7be971..aa567d8541d 100644 --- a/opcodes/epiphany-ibld.c +++ b/opcodes/epiphany-ibld.c @@ -1092,7 +1092,7 @@ epiphany_cgen_extract_operand (CGEN_CPU_DESC cd, length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8); if (length <= 0) break; { - FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21)); + FLD (f_sdisp11) = ((((((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) & (2047))) ^ (1024))) - (1024)); } } break; diff --git a/opcodes/lm32-ibld.c b/opcodes/lm32-ibld.c index 4bc63fb329c..a79398d46a5 100644 --- a/opcodes/lm32-ibld.c +++ b/opcodes/lm32-ibld.c @@ -680,7 +680,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, { long value; length = extract_normal (cd, ex_info, insn_value, 0|(1<> (14)))); + value = ((pc) + (((((((((value) & (65535))) << (2))) ^ (131072))) - (131072)))); fields->f_branch = value; } break; @@ -688,7 +688,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, { long value; length = extract_normal (cd, ex_info, insn_value, 0|(1<> (4)))); + value = ((pc) + (((((((((value) & (67108863))) << (2))) ^ (134217728))) - (134217728)))); fields->f_call = value; } break; diff --git a/opcodes/m32c-ibld.c b/opcodes/m32c-ibld.c index 29c9411a279..8473e17d209 100644 --- a/opcodes/m32c-ibld.c +++ b/opcodes/m32c-ibld.c @@ -1489,7 +1489,7 @@ m32c_cgen_insert_operand (CGEN_CPU_DESC cd, case M32C_OPERAND_LAB_8_16 : { long value = fields->f_lab_8_16; - value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65535))) >> (8)))); + value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65280))) >> (8)))); errmsg = insert_normal (cd, value, 0|(1<> (8))) | (((SI) (((((value) & (255))) << (24))) >> (16))))) + (((pc) + (1)))); + value = ((((((((((USI) (((value) & (65280))) >> (8))) | (((((value) & (255))) << (8))))) ^ (32768))) - (32768))) + (((pc) + (1)))); fields->f_lab_8_16 = value; } break; diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c index adf0091b2a0..731860c4098 100644 --- a/opcodes/nios2-dis.c +++ b/opcodes/nios2-dis.c @@ -554,10 +554,10 @@ nios2_print_insn_arg (const char *argptr, switch (op->format) { case iw_i_type: - s = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; + s = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; break; case iw_F2I16_type: - s = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; + s = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; break; default: bad_opcode (op); @@ -570,10 +570,10 @@ nios2_print_insn_arg (const char *argptr, switch (op->format) { case iw_F2X4I12_type: - s = (int32_t) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20; + s = ((GET_IW_F2X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; break; case iw_F1X4I12_type: - s = (int32_t) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20; + s = ((GET_IW_F1X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; break; default: bad_opcode (op); @@ -673,10 +673,10 @@ nios2_print_insn_arg (const char *argptr, switch (op->format) { case iw_i_type: - o = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; + o = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; break; case iw_F2I16_type: - o = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; + o = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; break; default: bad_opcode (op); @@ -690,7 +690,7 @@ nios2_print_insn_arg (const char *argptr, switch (op->format) { case iw_I10_type: - o = (int32_t) (GET_IW_I10_IMM10 (opcode) << 22) >> 21; + o = (((GET_IW_I10_IMM10 (opcode) & 0x3ff) ^ 0x400) - 0x400) << 1; break; default: bad_opcode (op); @@ -704,7 +704,7 @@ nios2_print_insn_arg (const char *argptr, switch (op->format) { case iw_T1I7_type: - o = (int32_t) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24; + o = (((GET_IW_T1I7_IMM7 (opcode) & 0x7f) ^ 0x40) - 0x40) << 1; break; default: bad_opcode (op); diff --git a/opcodes/pdp11-dis.c b/opcodes/pdp11-dis.c index e9708e639ee..a19fbc0f3d9 100644 --- a/opcodes/pdp11-dis.c +++ b/opcodes/pdp11-dis.c @@ -31,8 +31,7 @@ #define F info->stream /* Sign-extend a 16-bit number in an int. */ -#define SIGN_BITS (8 * sizeof (int) - 16) -#define sign_extend(x) (((x) << SIGN_BITS) >> SIGN_BITS) +#define sign_extend(x) ((((x) & 0xffff) ^ 0x8000) - 0x8000) static int read_word (bfd_vma memaddr, int *word, disassemble_info *info) diff --git a/opcodes/tic54x-dis.c b/opcodes/tic54x-dis.c index c4ecdda1876..d8b80a3bf7d 100644 --- a/opcodes/tic54x-dis.c +++ b/opcodes/tic54x-dis.c @@ -394,8 +394,7 @@ print_instruction (disassemble_info *info, break; } case OP_k5: - sprintf (operand[i], "#%d", - (int) (((signed char) opcode & 0x1F) << 3) >> 3); + sprintf (operand[i], "#%d", ((opcode & 0x1F) ^ 0x10) - 0x10); info->fprintf_func (info->stream, "%s%s", comma, operand[i]); break; case OP_k8u: diff --git a/opcodes/tilegx-opc.c b/opcodes/tilegx-opc.c index 49819e8453f..cc9ce861b9a 100644 --- a/opcodes/tilegx-opc.c +++ b/opcodes/tilegx-opc.c @@ -8102,8 +8102,8 @@ parse_insn_tilegx (tilegx_bundle_bits bits, if (op->is_signed) { /* Sign-extend the operand. */ - int shift = (int)((sizeof(int) * 8) - op->num_bits); - raw_opval = (raw_opval << shift) >> shift; + unsigned int sign = 1u << (op->num_bits - 1); + raw_opval = ((raw_opval & (sign + sign - 1)) ^ sign) - sign; } /* Adjust PC-relative scaled branch offsets. */ diff --git a/opcodes/tilepro-opc.c b/opcodes/tilepro-opc.c index ea158222ead..c71da3df8a1 100644 --- a/opcodes/tilepro-opc.c +++ b/opcodes/tilepro-opc.c @@ -10220,8 +10220,8 @@ parse_insn_tilepro (tilepro_bundle_bits bits, if (op->is_signed) { /* Sign-extend the operand. */ - int shift = (int)((sizeof(int) * 8) - op->num_bits); - opval = (opval << shift) >> shift; + unsigned int sign = 1u << (op->num_bits - 1); + opval = ((opval & (sign + sign - 1)) ^ sign) - sign; } /* Adjust PC-relative scaled branch offsets. */ diff --git a/opcodes/visium-dis.c b/opcodes/visium-dis.c index c71f8cf25ab..41943ade726 100644 --- a/opcodes/visium-dis.c +++ b/opcodes/visium-dis.c @@ -94,7 +94,7 @@ disassem_class0 (disassemble_info *info, unsigned int ins) /* BRR instruction. */ { unsigned cbf = (ins >> 27) & 0x000f; - int displacement = ((int) (ins << 16)) >> 16; + int displacement = ((ins & 0xffff) ^ 0x8000) - 0x8000; if (ins == 0) (*info->fprintf_func) (info->stream, "nop");