ARM: Fix some bugs in the ISA desc and fill out some instructions.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 11 Nov 2009 07:44:05 +0000 (23:44 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 11 Nov 2009 07:44:05 +0000 (23:44 -0800)
src/arch/arm/isa/bitfields.isa
src/arch/arm/isa/decoder.isa
src/arch/arm/isa/formats/pred.isa
src/arch/arm/isa/operands.isa
src/arch/arm/types.hh

index 5785939cc5a59877c4743fe7a85c9636f6ffa7cb..fc75ecf79218b3cad1623e6399fbfb4f54b04a1c 100644 (file)
@@ -43,6 +43,7 @@ def bitfield OPCODE_23_20  opcode23_20;
 def bitfield OPCODE_23_21  opcode23_21;
 def bitfield OPCODE_22     opcode22;
 def bitfield OPCODE_19    opcode19;
+def bitfield OPCODE_18    opcode18;
 def bitfield OPCODE_15_12  opcode15_12;
 def bitfield OPCODE_15    opcode15;
 def bitfield MISC_OPCODE   miscOpcode;
index ebadeb9852718b78b5bc3aed895f0554900b4278..b4b820b06a3c23932c0852fa47e1aac37fffa23b 100644 (file)
@@ -51,20 +51,25 @@ format DataOp {
                         resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
                         Rd = (uint32_t)(resTemp & 0xffffffff);
                         Rn = (uint32_t)(resTemp >> 32);
-                    }});
-                    0x5: WarnUnimpl::smlal();
+                    }}, llbit);
+                    0x5: smlal({{ 
+                        resTemp = ((int64_t)Rm) * ((int64_t)Rs); 
+                        resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); 
+                        Rd = (uint32_t)(resTemp & 0xffffffff);
+                        Rn = (uint32_t)(resTemp >> 32);
+                    }}, llbit);
                     0x6: smull({{
                         resTemp = ((int64_t)(int32_t)Rm)*
                                   ((int64_t)(int32_t)Rs);
                         Rd = (int32_t)(resTemp & 0xffffffff);
                         Rn = (int32_t)(resTemp >> 32);
-                    }});
+                    }}, llbit);
                     0x7: umlal({{
                         resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
                         resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
                         Rd = (uint32_t)(resTemp & 0xffffffff);
                         Rn = (uint32_t)(resTemp >> 32);
-                    }});
+                    }}, llbit);
                 }
                 1: decode PUBWL {
                     0x10: WarnUnimpl::swp();
@@ -105,9 +110,17 @@ format DataOp {
             }
             1: decode MISC_OPCODE {
                 0x0: decode OPCODE {
-                    0x8: WarnUnimpl::mrs_cpsr();
-                    0x9: WarnUnimpl::msr_cpsr();
-                    0xa: WarnUnimpl::mrs_spsr();
+                    0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }});
+                    0x9: PredOp::msr_cpsr({{
+                        //assert(!RN<1:0>);
+                        if (OPCODE_18) {
+                            Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>;
+                        }
+                        if (OPCODE_19) {
+                            CondCodes = mbits(Rm, 31,27);
+                        }
+                    }});
+                    0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}});
                     0xb: WarnUnimpl::msr_spsr();
                 }
                 0x1: decode OPCODE {
@@ -129,28 +142,32 @@ format DataOp {
                     0xb: WarnUnimpl::qdsub();
                 }
                 0x8: decode OPCODE {
-                    0x8: WarnUnimpl::smlabb();
+                    0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
                     0x9: WarnUnimpl::smlalbb();
                     0xa: WarnUnimpl::smlawb();
-                    0xb: WarnUnimpl::smulbb();
+                    0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
                 }
                 0xa: decode OPCODE {
-                    0x8: WarnUnimpl::smlatb();
-                    0x9: WarnUnimpl::smulwb();
+                    0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
+                    0x9: smulwb({{ 
+                        Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); 
+                    }}, none);
                     0xa: WarnUnimpl::smlaltb();
-                    0xb: WarnUnimpl::smultb();
+                    0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
                 }
                 0xc: decode OPCODE {
-                    0x8: WarnUnimpl::smlabt();
+                    0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
                     0x9: WarnUnimpl::smlawt();
                     0xa: WarnUnimpl::smlalbt();
-                    0xb: WarnUnimpl::smulbt();
+                    0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
                 }
                 0xe: decode OPCODE {
-                    0x8: WarnUnimpl::smlatt();
-                    0x9: WarnUnimpl::smulwt();
+                    0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
+                    0x9: smulwt({{ 
+                        Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); 
+                    }}, none);
                     0xa: WarnUnimpl::smlaltt();
-                    0xb: WarnUnimpl::smultt();
+                    0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
                 }
             }
         }
@@ -184,8 +201,16 @@ format DataOp {
         }
         1: decode OPCODE {
             // The following two instructions aren't supposed to be defined
-            0x8: WarnUnimpl::undefined_instruction();
-            0x9: WarnUnimpl::undefined_instruction();
+            0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
+            0x9: DataImmOp::msr_ia_cpsr ({{ 
+                    //assert(!RN<1:0>);
+                    if (OPCODE_18) {
+                        Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>;
+                    }
+                    if (OPCODE_19) {
+                        CondCodes = rotated_imm;
+                    }
+            }});
 
             0xa: WarnUnimpl::mrs_i_cpsr();
             0xb: WarnUnimpl::mrs_i_spsr();
@@ -440,6 +465,7 @@ format DataOp {
                     }
                 }
             }
+            0xf: WarnUnimpl::mcr_cp15();
         }
         format PredOp {
             // ARM System Call (SoftWare Interrupt)
index 3c97560fdef1b1fb31cb0f6b13d1b92d2d734389..0d6ee32f7d11e35427389376b8f0f6027a647439 100644 (file)
@@ -81,32 +81,45 @@ def template DataImmDecode {{
 }};
 
 let {{
+     calcCcCode = '''
+        if (%(canOverflow)s){
+           cprintf("canOverflow: %%d\\n", Rd < resTemp);
+           replaceBits(CondCodes, 27, Rd < resTemp);
+        } else {
+            uint16_t _ic, _iv, _iz, _in;
+            _in = (resTemp >> %(negBit)d) & 1;
+            _iz = (resTemp == 0);
+            _iv = %(ivValue)s & 1;
+            _ic = %(icValue)s & 1;
+            
+            CondCodes =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+                (CondCodes & 0x0FFFFFFF);
 
-    calcCcCode = '''
-        uint16_t _ic, _iv, _iz, _in;
-
-        _in = (resTemp >> 31) & 1;
-        _iz = (resTemp == 0);
-        _iv = %(ivValue)s & 1;
-        _ic = %(icValue)s & 1;
-
-        CondCodes =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
-            (CondCodes & 0x0FFFFFFF);
-
-        DPRINTF(Arm, "in = %%d\\n", _in);
-        DPRINTF(Arm, "iz = %%d\\n", _iz);
-        DPRINTF(Arm, "ic = %%d\\n", _ic);
-        DPRINTF(Arm, "iv = %%d\\n", _iv);
+            DPRINTF(Arm, "in = %%d\\n", _in);
+            DPRINTF(Arm, "iz = %%d\\n", _iz);
+            DPRINTF(Arm, "ic = %%d\\n", _ic);
+            DPRINTF(Arm, "iv = %%d\\n", _iv);
+        }
         '''
-
 }};
 
 let {{
     def getCcCode(flagtype):
         icReg = icImm = iv = ''
+        negBit = 31
+        canOverflow = 'false'
+
         if flagtype == "none":
             icReg = icImm = 'CondCodes<29:>'
             iv = 'CondCodes<28:>'
+        elif flagtype == "llbit":
+            icReg = icImm = 'CondCodes<29:>'
+            iv = 'CondCodes<28:>'
+            negBit = 63
+        elif flagtype == "overflow":
+            canOverflow = "true" 
+            icReg = icImm = iv = '0'
         elif flagtype == "add":
             icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
             iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -117,17 +130,32 @@ let {{
             icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
             iv = 'findOverflow(32, resTemp, op2, ~Rn)'
         else:
-            icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)'
+            icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
             icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
             iv = 'CondCodes<28:>'
-        return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
-                calcCcCode % {"icValue" : icImm, "ivValue" : iv})
+        return (calcCcCode % {"icValue" : icReg, 
+                              "ivValue" : iv, 
+                              "negBit" : negBit,
+                              "canOverflow" : canOverflow },
+               calcCcCode % {"icValue" : icImm, 
+                              "ivValue" : iv, 
+                              "negBit" : negBit,
+                              "canOverflow" : canOverflow })
 
     def getImmCcCode(flagtype):
         ivValue = icValue = ''
+        negBit = 31
+        canOverflow = 'false'
         if flagtype == "none":
             icValue = 'CondCodes<29:>'
             ivValue = 'CondCodes<28:>'
+        elif flagtype == "llbit":
+            icValue = 'CondCodes<29:>'
+            ivValue = 'CondCodes<28:>'
+            negBit = 63
+        elif flagtype == "overflow":
+            icVaule = ivValue = '0'
+            canOverflow = "true" 
         elif flagtype == "add":
             icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
             ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
@@ -145,11 +173,11 @@ let {{
 
 def format DataOp(code, flagtype = logic) {{
     (regCcCode, immCcCode) = getCcCode(flagtype)
-    regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
-                                            shift, CondCodes<29:0>);
+    regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
+                                            shift, CondCodes<29:>);
                  op2 = op2;''' + code
     immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
-                                             shift, CondCodes<29:0>);
+                                             shift, CondCodes<29:>);
                  op2 = op2;''' + code
     regIop = InstObjParams(name, Name, 'PredIntOp',
                            {"code": regCode,
index 02acc8ed707b15cecc6ea435376ee88b09dfe746..5ae0b8912debaa3632ac1a36d3d810c450f28de4 100644 (file)
@@ -58,6 +58,7 @@ def operands {{
     'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
     'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
     'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
+    'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
 
     #Destination register for load/store double instructions
     'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
index d5cc07eaf68d51edd50f1fd4097d23afea39f4f1..237bf8412bd078ed451ee3f5368541ca09bbe7af 100644 (file)
@@ -52,6 +52,7 @@ namespace ArmISA
         Bitfield<23, 21> opcode23_21;
         Bitfield<22>     opcode22;
         Bitfield<19>     opcode19;
+        Bitfield<18>     opcode18;
         Bitfield<15, 12> opcode15_12;
         Bitfield<15>     opcode15;
         Bitfield<7,  4>  miscOpcode;