GNU Binutils with patches for OS216
修訂 | 1d61b032265e69317f42e8019e072506f11890c5 (tree) |
---|---|
時間 | 2019-12-11 19:44:19 |
作者 | Alan Modra <amodra@gmai...> |
Commiter | Alan Modra |
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.
@@ -1,5 +1,11 @@ | ||
1 | 1 | 2019-12-11 Alan Modra <amodra@gmail.com> |
2 | 2 | |
3 | + * epiphany.cpu (f-sdisp11): Don't sign extend with shifts. | |
4 | + * lm32.cpu (f-branch, f-vall): Likewise. | |
5 | + * m32.cpu (f-lab-8-16): Likewise. | |
6 | + | |
7 | +2019-12-11 Alan Modra <amodra@gmail.com> | |
8 | + | |
3 | 9 | * epiphany.cpu (f-simm8, f-simm24): Use multiply rather than |
4 | 10 | shift left to avoid UB on left shift of negative values. |
5 | 11 |
@@ -228,10 +228,11 @@ | ||
228 | 228 | (set (ifield f-disp3) (and SI (ifield f-sdisp11) 7))) |
229 | 229 | (sequence () ;decode |
230 | 230 | (set (ifield f-sdisp11) |
231 | - (sra SI (sll SI (or SI (sll (ifield f-disp8) 3) | |
232 | - (ifield f-disp3)) | |
233 | - 21) | |
234 | - 21))) | |
231 | + (sub SI (xor (and (or (sll (ifield f-disp8) 3) | |
232 | + (ifield f-disp3)) | |
233 | + #x7ff) | |
234 | + #x400) | |
235 | + #x400))) | |
235 | 236 | ) |
236 | 237 | |
237 | 238 | (dnmf f-imm16 "Short immediate for move/add/sub" () UINT (f-imm8 f-imm-27-8) |
@@ -128,11 +128,15 @@ | ||
128 | 128 | |
129 | 129 | (df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT |
130 | 130 | ((value pc) (sra SI (sub SI value pc) 2)) |
131 | - ((value pc) (add SI pc (sra SI (sll SI value 16) 14))) | |
131 | + ((value pc) (add SI pc (sub (xor (sll (and value #xffff) 2) | |
132 | + #x20000) | |
133 | + #x20000))) | |
132 | 134 | ) |
133 | 135 | (df f-call "call offset field" (PCREL-ADDR) 25 26 INT |
134 | 136 | ((value pc) (sra SI (sub SI value pc) 2)) |
135 | - ((value pc) (add SI pc (sra SI (sll SI value 6) 4))) | |
137 | + ((value pc) (add SI pc (sub (xor (sll (and value #x3ffffff) 2) | |
138 | + #x8000000) | |
139 | + #x8000000))) | |
136 | 140 | ) |
137 | 141 | |
138 | 142 |
@@ -956,9 +956,12 @@ | ||
956 | 956 | ) |
957 | 957 | (df f-lab-8-16 "16 bit pc relative signed offset" (PCREL-ADDR SIGN-OPT all-isas) 8 16 UINT |
958 | 958 | ((value pc) (or SI (sll (and (sub value (add pc 1)) #xff) 8) |
959 | - (srl (and (sub value (add pc 1)) #xffff) 8))) | |
960 | - ((value pc) (add SI (or (srl (and value #xffff) 8) | |
961 | - (sra (sll (and value #xff) 24) 16)) (add pc 1))) | |
959 | + (srl (and (sub value (add pc 1)) #xff00) 8))) | |
960 | + ((value pc) (add SI (sub (xor (or (srl (and value #xff00) 8) | |
961 | + (sll (and value #xff) 8)) | |
962 | + #x8000) | |
963 | + #x8000) | |
964 | + (add pc 1))) | |
962 | 965 | ) |
963 | 966 | (df f-lab-8-24 "24 bit absolute" (all-isas ABS-ADDR) 8 24 UINT |
964 | 967 | ((value pc) (or SI |
@@ -1,5 +1,19 @@ | ||
1 | 1 | 2019-12-11 Alan Modra <amodra@gmail.com> |
2 | 2 | |
3 | + * arc-dis.c (BITS): Don't truncate high bits with shifts. | |
4 | + * nios2-dis.c (nios2_print_insn_arg): Don't sign extend with shifts. | |
5 | + * tic54x-dis.c (print_instruction): Likewise. | |
6 | + * tilegx-opc.c (parse_insn_tilegx): Likewise. | |
7 | + * tilepro-opc.c (parse_insn_tilepro): Likewise. | |
8 | + * visium-dis.c (disassem_class0): Likewise. | |
9 | + * pdp11-dis.c (sign_extend): Likewise. | |
10 | + (SIGN_BITS): Delete. | |
11 | + * epiphany-ibld.c: Regenerate. | |
12 | + * lm32-ibld.c: Regenerate. | |
13 | + * m32c-ibld.c: Regenerate. | |
14 | + | |
15 | +2019-12-11 Alan Modra <amodra@gmail.com> | |
16 | + | |
3 | 17 | * ns32k-dis.c (sign_extend): Correct last patch. |
4 | 18 | |
5 | 19 | 2019-12-11 Alan Modra <amodra@gmail.com> |
@@ -137,8 +137,7 @@ static bfd_boolean print_hex = FALSE; | ||
137 | 137 | (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \ |
138 | 138 | : bfd_getb32 (buf)) |
139 | 139 | |
140 | -#define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \ | |
141 | - (s + (sizeof (word) * 8 - 1 - e))) | |
140 | +#define BITS(word,s,e) (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1)) | |
142 | 141 | #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31)) |
143 | 142 | |
144 | 143 | /* Functions implementation. */ |
@@ -1092,7 +1092,7 @@ epiphany_cgen_extract_operand (CGEN_CPU_DESC cd, | ||
1092 | 1092 | length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8); |
1093 | 1093 | if (length <= 0) break; |
1094 | 1094 | { |
1095 | - FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21)); | |
1095 | + FLD (f_sdisp11) = ((((((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) & (2047))) ^ (1024))) - (1024)); | |
1096 | 1096 | } |
1097 | 1097 | } |
1098 | 1098 | break; |
@@ -680,7 +680,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, | ||
680 | 680 | { |
681 | 681 | long value; |
682 | 682 | 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); |
683 | - value = ((pc) + (((SI) (((value) << (16))) >> (14)))); | |
683 | + value = ((pc) + (((((((((value) & (65535))) << (2))) ^ (131072))) - (131072)))); | |
684 | 684 | fields->f_branch = value; |
685 | 685 | } |
686 | 686 | break; |
@@ -688,7 +688,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, | ||
688 | 688 | { |
689 | 689 | long value; |
690 | 690 | 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); |
691 | - value = ((pc) + (((SI) (((value) << (6))) >> (4)))); | |
691 | + value = ((pc) + (((((((((value) & (67108863))) << (2))) ^ (134217728))) - (134217728)))); | |
692 | 692 | fields->f_call = value; |
693 | 693 | } |
694 | 694 | break; |
@@ -1489,7 +1489,7 @@ m32c_cgen_insert_operand (CGEN_CPU_DESC cd, | ||
1489 | 1489 | case M32C_OPERAND_LAB_8_16 : |
1490 | 1490 | { |
1491 | 1491 | long value = fields->f_lab_8_16; |
1492 | - value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65535))) >> (8)))); | |
1492 | + value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65280))) >> (8)))); | |
1493 | 1493 | errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGN_OPT)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 16, 32, total_length, buffer); |
1494 | 1494 | } |
1495 | 1495 | break; |
@@ -2654,7 +2654,7 @@ m32c_cgen_extract_operand (CGEN_CPU_DESC cd, | ||
2654 | 2654 | { |
2655 | 2655 | long value; |
2656 | 2656 | 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); |
2657 | - value = ((((((USI) (((value) & (65535))) >> (8))) | (((SI) (((((value) & (255))) << (24))) >> (16))))) + (((pc) + (1)))); | |
2657 | + value = ((((((((((USI) (((value) & (65280))) >> (8))) | (((((value) & (255))) << (8))))) ^ (32768))) - (32768))) + (((pc) + (1)))); | |
2658 | 2658 | fields->f_lab_8_16 = value; |
2659 | 2659 | } |
2660 | 2660 | break; |
@@ -554,10 +554,10 @@ nios2_print_insn_arg (const char *argptr, | ||
554 | 554 | switch (op->format) |
555 | 555 | { |
556 | 556 | case iw_i_type: |
557 | - s = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; | |
557 | + s = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; | |
558 | 558 | break; |
559 | 559 | case iw_F2I16_type: |
560 | - s = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; | |
560 | + s = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; | |
561 | 561 | break; |
562 | 562 | default: |
563 | 563 | bad_opcode (op); |
@@ -570,10 +570,10 @@ nios2_print_insn_arg (const char *argptr, | ||
570 | 570 | switch (op->format) |
571 | 571 | { |
572 | 572 | case iw_F2X4I12_type: |
573 | - s = (int32_t) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20; | |
573 | + s = ((GET_IW_F2X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; | |
574 | 574 | break; |
575 | 575 | case iw_F1X4I12_type: |
576 | - s = (int32_t) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20; | |
576 | + s = ((GET_IW_F1X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; | |
577 | 577 | break; |
578 | 578 | default: |
579 | 579 | bad_opcode (op); |
@@ -673,10 +673,10 @@ nios2_print_insn_arg (const char *argptr, | ||
673 | 673 | switch (op->format) |
674 | 674 | { |
675 | 675 | case iw_i_type: |
676 | - o = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; | |
676 | + o = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; | |
677 | 677 | break; |
678 | 678 | case iw_F2I16_type: |
679 | - o = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; | |
679 | + o = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; | |
680 | 680 | break; |
681 | 681 | default: |
682 | 682 | bad_opcode (op); |
@@ -690,7 +690,7 @@ nios2_print_insn_arg (const char *argptr, | ||
690 | 690 | switch (op->format) |
691 | 691 | { |
692 | 692 | case iw_I10_type: |
693 | - o = (int32_t) (GET_IW_I10_IMM10 (opcode) << 22) >> 21; | |
693 | + o = (((GET_IW_I10_IMM10 (opcode) & 0x3ff) ^ 0x400) - 0x400) << 1; | |
694 | 694 | break; |
695 | 695 | default: |
696 | 696 | bad_opcode (op); |
@@ -704,7 +704,7 @@ nios2_print_insn_arg (const char *argptr, | ||
704 | 704 | switch (op->format) |
705 | 705 | { |
706 | 706 | case iw_T1I7_type: |
707 | - o = (int32_t) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24; | |
707 | + o = (((GET_IW_T1I7_IMM7 (opcode) & 0x7f) ^ 0x40) - 0x40) << 1; | |
708 | 708 | break; |
709 | 709 | default: |
710 | 710 | bad_opcode (op); |
@@ -31,8 +31,7 @@ | ||
31 | 31 | #define F info->stream |
32 | 32 | |
33 | 33 | /* Sign-extend a 16-bit number in an int. */ |
34 | -#define SIGN_BITS (8 * sizeof (int) - 16) | |
35 | -#define sign_extend(x) (((x) << SIGN_BITS) >> SIGN_BITS) | |
34 | +#define sign_extend(x) ((((x) & 0xffff) ^ 0x8000) - 0x8000) | |
36 | 35 | |
37 | 36 | static int |
38 | 37 | read_word (bfd_vma memaddr, int *word, disassemble_info *info) |
@@ -394,8 +394,7 @@ print_instruction (disassemble_info *info, | ||
394 | 394 | break; |
395 | 395 | } |
396 | 396 | case OP_k5: |
397 | - sprintf (operand[i], "#%d", | |
398 | - (int) (((signed char) opcode & 0x1F) << 3) >> 3); | |
397 | + sprintf (operand[i], "#%d", ((opcode & 0x1F) ^ 0x10) - 0x10); | |
399 | 398 | info->fprintf_func (info->stream, "%s%s", comma, operand[i]); |
400 | 399 | break; |
401 | 400 | case OP_k8u: |
@@ -8102,8 +8102,8 @@ parse_insn_tilegx (tilegx_bundle_bits bits, | ||
8102 | 8102 | if (op->is_signed) |
8103 | 8103 | { |
8104 | 8104 | /* Sign-extend the operand. */ |
8105 | - int shift = (int)((sizeof(int) * 8) - op->num_bits); | |
8106 | - raw_opval = (raw_opval << shift) >> shift; | |
8105 | + unsigned int sign = 1u << (op->num_bits - 1); | |
8106 | + raw_opval = ((raw_opval & (sign + sign - 1)) ^ sign) - sign; | |
8107 | 8107 | } |
8108 | 8108 | |
8109 | 8109 | /* Adjust PC-relative scaled branch offsets. */ |
@@ -10220,8 +10220,8 @@ parse_insn_tilepro (tilepro_bundle_bits bits, | ||
10220 | 10220 | if (op->is_signed) |
10221 | 10221 | { |
10222 | 10222 | /* Sign-extend the operand. */ |
10223 | - int shift = (int)((sizeof(int) * 8) - op->num_bits); | |
10224 | - opval = (opval << shift) >> shift; | |
10223 | + unsigned int sign = 1u << (op->num_bits - 1); | |
10224 | + opval = ((opval & (sign + sign - 1)) ^ sign) - sign; | |
10225 | 10225 | } |
10226 | 10226 | |
10227 | 10227 | /* Adjust PC-relative scaled branch offsets. */ |
@@ -94,7 +94,7 @@ disassem_class0 (disassemble_info *info, unsigned int ins) | ||
94 | 94 | /* BRR instruction. */ |
95 | 95 | { |
96 | 96 | unsigned cbf = (ins >> 27) & 0x000f; |
97 | - int displacement = ((int) (ins << 16)) >> 16; | |
97 | + int displacement = ((ins & 0xffff) ^ 0x8000) - 0x8000; | |
98 | 98 | |
99 | 99 | if (ins == 0) |
100 | 100 | (*info->fprintf_func) (info->stream, "nop"); |