Remove more shifts for sign/zero extension
authorAlan Modra <amodra@gmail.com>
Wed, 11 Dec 2019 06:15:14 +0000 (16:45 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 11 Dec 2019 10:44:19 +0000 (21:14 +1030)
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.

15 files changed:
cpu/ChangeLog
cpu/epiphany.cpu
cpu/lm32.cpu
cpu/m32c.cpu
opcodes/ChangeLog
opcodes/arc-dis.c
opcodes/epiphany-ibld.c
opcodes/lm32-ibld.c
opcodes/m32c-ibld.c
opcodes/nios2-dis.c
opcodes/pdp11-dis.c
opcodes/tic54x-dis.c
opcodes/tilegx-opc.c
opcodes/tilepro-opc.c
opcodes/visium-dis.c

index fd26cb78b4b8256e8c07b49d32637e7be5ab9e9a..c5a44ab45f0f63b579d9aecbc24203c50d4eb046 100644 (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
index 9f873b38f47bc254aaff6b73dc0cda86108546f0..02bce0779d5db97b06dd54b5cd53cc88fdd41a54 100644 (file)
                (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)
index 83c839f3392f857bca6f062ef07413a0ac594b31..ecd8160816efce2ba20896089763c86cdc5a5f5b 100644 (file)
 
 (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)))
 )
 
 \f
index bcc36161f7cb374c98ee1f010acb2b16b8768a1b..5a38f1bd5264a574ae95c8569dc3d02fd185466b 100644 (file)
 )
 (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
index 5345dfb2bf75e74ddb9e039022983643017e32cb..2a44855e4f7cc7ee74d854ac16d889cbe231e84a 100644 (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.
index a038fa0ca27f26445f886f8cb87b8313dcce412a..a47e81f0a28be49522bb9e2e38bb43ec0b7c0b93 100644 (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.  */
index 6e6fd7be9714919e2af7daec2c83d6e38194941e..aa567d8541dfb217dac3e8623202f718a1c34964 100644 (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;
index 4bc63fb329c8ae9a4dc9cbbb765bc12181f70313..a79398d46a5f6d714d2e5883c361711d8bfd0881 100644 (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;
index 29c9411a279f1e515e5bec4170d6d686a366dcd9..8473e17d2090e489b6cec5bcceb3f1e05165d4ba 100644 (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;
index adf0091b2a0c16df679ac0dcc875809fb7468ad9..731860c40986881ac64be6a43333cbddd195ea50 100644 (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);
index e9708e639eeac8abdc6475ca6fd6ebad014c12ee..a19fbc0f3d9d6ccd8b67a6ffc55cd48dd72e55c5 100644 (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)
index c4ecdda1876511dc23da7daeb3c94d7ac5ecb28a..d8b80a3bf7dbb45492e955ba14ba917650c5906f 100644 (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:
index 49819e8453f0924771b2064aec5b026f4075a2ae..cc9ce861b9a506cececa8c4f72fad563b443e47b 100644 (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.  */
index ea158222eada7b34ce9bab03f721dd169a145dc4..c71da3df8a11c04796cbbe0d45426614884cf0e6 100644 (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.  */
index c71f8cf25ab3aea3270aa711ede5df5f6cb529c8..41943ade7264b73b2c3eae33baf93ae231c3042b 100644 (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");