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.
This commit is contained in:
Alan Modra 2019-12-11 16:45:14 +10:30
parent 13c9c48599
commit 1d61b03226
15 changed files with 58 additions and 33 deletions

View File

@ -1,3 +1,9 @@
2019-12-11 Alan Modra <amodra@gmail.com>
* 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 <amodra@gmail.com>
* epiphany.cpu (f-simm8, f-simm24): Use multiply rather than

View File

@ -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)

View File

@ -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)))
)

View File

@ -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

View File

@ -1,3 +1,17 @@
2019-12-11 Alan Modra <amodra@gmail.com>
* 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 <amodra@gmail.com>
* ns32k-dis.c (sign_extend): Correct last patch.

View File

@ -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. */

View File

@ -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;

View File

@ -680,7 +680,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd,
{
long value;
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value);
value = ((pc) + (((SI) (((value) << (16))) >> (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<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, pc, & value);
value = ((pc) + (((SI) (((value) << (6))) >> (4))));
value = ((pc) + (((((((((value) & (67108863))) << (2))) ^ (134217728))) - (134217728))));
fields->f_call = value;
}
break;

View File

@ -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<<CGEN_IFLD_SIGN_OPT)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 16, 32, total_length, buffer);
}
break;
@ -2654,7 +2654,7 @@ m32c_cgen_extract_operand (CGEN_CPU_DESC cd,
{
long value;
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 16, 32, total_length, pc, & value);
value = ((((((USI) (((value) & (65535))) >> (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;

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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. */

View File

@ -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. */

View File

@ -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");