syscall_emul: [patch 13/22] add system call retry capability
[gem5.git] / src / arch / alpha / isa / decoder.isa
index 4bbf83cce3c8289104c2532fe0758427d098fcd5..8789fa905506b11bd4abb0e85a5566d7332257bf 100644 (file)
@@ -1,5 +1,17 @@
 // -*- mode:c++ -*-
 
+// Copyright (c) 2013 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
 // Copyright (c) 2003-2006 The Regents of The University of Michigan
 // All rights reserved.
 //
@@ -108,7 +120,7 @@ decode OPCODE default Unknown::unknown() {
                 // signed overflow occurs when operands have same sign
                 // and sign of result does not match.
                 if (Ra_sl<31:> == Rb_or_imm_sl<31:> && tmp<31:> != Ra_sl<31:>)
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc_sl = tmp;
             }});
             0x02: s4addl({{ Rc_sl = (Ra_sl << 2) + Rb_or_imm_sl; }});
@@ -120,7 +132,7 @@ decode OPCODE default Unknown::unknown() {
                 // signed overflow occurs when operands have same sign
                 // and sign of result does not match.
                 if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc = tmp;
             }});
             0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }});
@@ -134,7 +146,7 @@ decode OPCODE default Unknown::unknown() {
                 // sign bit of the subtrahend (Rb), i.e., if the initial
                 // signs are the *same* then no overflow can occur
                 if (Ra_sl<31:> != Rb_or_imm_sl<31:> && tmp<31:> != Ra_sl<31:>)
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc_sl = tmp;
             }});
             0x0b: s4subl({{ Rc_sl = (Ra_sl << 2) - Rb_or_imm_sl; }});
@@ -148,7 +160,7 @@ decode OPCODE default Unknown::unknown() {
                 // sign bit of the subtrahend (Rb), i.e., if the initial
                 // signs are the *same* then no overflow can occur
                 if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc = tmp;
             }});
             0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }});
@@ -301,7 +313,7 @@ decode OPCODE default Unknown::unknown() {
                 // checking the upper 33 bits for all 0s or all 1s.
                 uint64_t sign_bits = tmp<63:31>;
                 if (sign_bits != 0 && sign_bits != mask(33))
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc_sl = tmp<31:0>;
             }}, IntMultOp);
             0x60: mulqv({{
@@ -312,7 +324,7 @@ decode OPCODE default Unknown::unknown() {
                 // the lower 64
                 if (!((hi == 0 && lo<63:> == 0) ||
                       (hi == mask(64) && lo<63:> == 1)))
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Rc = lo;
             }}, IntMultOp);
         }
@@ -337,7 +349,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 0; i < 8; ++i) {
                                  uint8_t ra_ub = Ra_uq<hi:lo>;
                                  uint8_t rb_ub = Rb_uq<hi:lo>;
-                                 temp += (ra_ub >= rb_ub) ? 
+                                 temp += (ra_ub >= rb_ub) ?
                                          (ra_ub - rb_ub) : (rb_ub - ra_ub);
                                  hi += 8;
                                  lo += 8;
@@ -366,15 +378,15 @@ decode OPCODE default Unknown::unknown() {
                              if (!(temp<7:0>)) { temp >>= 8; count += 8; }
                              if (!(temp<3:0>)) { temp >>= 4; count += 4; }
                              if (!(temp<1:0>)) { temp >>= 2; count += 2; }
-                             if (!(temp<0:0> & ULL(0x1))) { 
-                                 temp >>= 1; count += 1; 
+                             if (!(temp<0:0> & ULL(0x1))) {
+                                 temp >>= 1; count += 1;
                              }
                              if (!(temp<0:0> & ULL(0x1))) count += 1;
                              Rc = count;
                            }}, IntAluOp);
 
 
-            0x34: unpkbw({{ 
+            0x34: unpkbw({{
                              Rc = (Rb_uq<7:0>
                                    | (Rb_uq<15:8> << 16)
                                    | (Rb_uq<23:16> << 32)
@@ -403,7 +415,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 7; i >= 0; --i) {
                                  int8_t ra_sb = Ra_uq<hi:lo>;
                                  int8_t rb_sb = Rb_uq<hi:lo>;
-                                 temp = ((temp << 8) 
+                                 temp = ((temp << 8)
                                          | ((ra_sb < rb_sb) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 8;
@@ -419,7 +431,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 3; i >= 0; --i) {
                                  int16_t ra_sw = Ra_uq<hi:lo>;
                                  int16_t rb_sw = Rb_uq<hi:lo>;
-                                 temp = ((temp << 16) 
+                                 temp = ((temp << 16)
                                          | ((ra_sw < rb_sw) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 16;
@@ -435,7 +447,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 7; i >= 0; --i) {
                                  uint8_t ra_ub = Ra_uq<hi:lo>;
                                  uint8_t rb_ub = Rb_uq<hi:lo>;
-                                 temp = ((temp << 8) 
+                                 temp = ((temp << 8)
                                          | ((ra_ub < rb_ub) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 8;
@@ -451,7 +463,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 3; i >= 0; --i) {
                                  uint16_t ra_sw = Ra_uq<hi:lo>;
                                  uint16_t rb_sw = Rb_uq<hi:lo>;
-                                 temp = ((temp << 16) 
+                                 temp = ((temp << 16)
                                          | ((ra_sw < rb_sw) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 16;
@@ -467,7 +479,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 7; i >= 0; --i) {
                                  uint8_t ra_ub = Ra_uq<hi:lo>;
                                  uint8_t rb_ub = Rb_uq<hi:lo>;
-                                 temp = ((temp << 8) 
+                                 temp = ((temp << 8)
                                          | ((ra_ub > rb_ub) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 8;
@@ -483,7 +495,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 3; i >= 0; --i) {
                                  uint16_t ra_uw = Ra_uq<hi:lo>;
                                  uint16_t rb_uw = Rb_uq<hi:lo>;
-                                 temp = ((temp << 16) 
+                                 temp = ((temp << 16)
                                          | ((ra_uw > rb_uw) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 16;
@@ -499,7 +511,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 7; i >= 0; --i) {
                                  int8_t ra_sb = Ra_uq<hi:lo>;
                                  int8_t rb_sb = Rb_uq<hi:lo>;
-                                 temp = ((temp << 8) 
+                                 temp = ((temp << 8)
                                          | ((ra_sb > rb_sb) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 8;
@@ -515,7 +527,7 @@ decode OPCODE default Unknown::unknown() {
                              for (int i = 3; i >= 0; --i) {
                                  int16_t ra_sw = Ra_uq<hi:lo>;
                                  int16_t rb_sw = Rb_uq<hi:lo>;
-                                 temp = ((temp << 16) 
+                                 temp = ((temp << 16)
                                          | ((ra_sw > rb_sw) ? Ra_uq<hi:lo>
                                                           : Rb_uq<hi:lo>));
                                  hi -= 16;
@@ -591,19 +603,19 @@ decode OPCODE default Unknown::unknown() {
 #if SS_COMPATIBLE_FP
                     0x0b: sqrts({{
                         if (Fb < 0.0)
-                            fault = new ArithmeticFault;
+                            fault = std::make_shared<ArithmeticFault>();
                         Fc = sqrt(Fb);
                     }}, FloatSqrtOp);
 #else
                     0x0b: sqrts({{
                         if (Fb_sf < 0.0)
-                            fault = new ArithmeticFault;
+                            fault = std::make_shared<ArithmeticFault>();
                         Fc_sf = sqrt(Fb_sf);
                     }}, FloatSqrtOp);
 #endif
                     0x2b: sqrtt({{
                         if (Fb < 0.0)
-                            fault = new ArithmeticFault;
+                            fault = std::make_shared<ArithmeticFault>();
                         Fc = sqrt(Fb);
                     }}, FloatSqrtOp);
                 }
@@ -734,7 +746,7 @@ decode OPCODE default Unknown::unknown() {
                 // checking the upper 33 bits for all 0s or all 1s.
                 uint64_t sign_bits = Fb_uq<63:31>;
                 if (sign_bits != 0 && sign_bits != mask(33))
-                    fault = new IntegerOverflowFault;
+                    fault = std::make_shared<IntegerOverflowFault>();
                 Fc_uq = (Fb_uq<31:30> << 62) | (Fb_uq<29:0> << 29);
             }});
 
@@ -805,14 +817,14 @@ decode OPCODE default Unknown::unknown() {
             0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp);
         }
 
-        0xe000: decode FullSystem {
+        0xe000: decode FullSystemInt {
             0: FailUnimpl::rc_se();
             default: BasicOperate::rc({{
                 Ra = IntrFlag;
                 IntrFlag = 0;
             }}, IsNonSpeculative, IsUnverifiable);
         }
-        0xf000: decode FullSystem {
+        0xf000: decode FullSystemInt {
             0: FailUnimpl::rs_se();
             default: BasicOperate::rs({{
                 Ra = IntrFlag;
@@ -821,14 +833,14 @@ decode OPCODE default Unknown::unknown() {
         }
     }
 
-    0x00: decode FullSystem {
+    0x00: decode FullSystemInt {
         0: decode PALFUNC {
             format EmulatedCallPal {
                 0x00: halt ({{
                     exitSimLoop("halt instruction encountered");
                 }}, IsNonSpeculative);
                 0x83: callsys({{
-                    xc->syscall(R0);
+                    xc->syscall(R0, &fault);
                 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
                 // Read uniq reg into ABI return value register (r0)
                 0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
@@ -842,7 +854,7 @@ decode OPCODE default Unknown::unknown() {
                  && xc->readMiscReg(IPR_ICM) != mode_kernel)) {
                 // invalid pal function code, or attempt to do privileged
                 // PAL call in non-kernel mode
-                fault = new UnimplementedOpcodeFault;
+                fault = std::make_shared<UnimplementedOpcodeFault>();
             } else {
                 // check to see if simulator wants to do something special
                 // on this PAL call (including maybe suppress it)
@@ -892,7 +904,7 @@ decode OPCODE default Unknown::unknown() {
                         IprToMiscRegIndex[ipr_index] : -1;
                 if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) ||
                     miscRegIndex >= NumInternalProcRegs)
-                        fault = new UnimplementedOpcodeFault;
+                    fault = std::make_shared<UnimplementedOpcodeFault>();
                 else
                     Ra = xc->readMiscReg(miscRegIndex);
             }}, IsIprAccess);
@@ -907,7 +919,7 @@ decode OPCODE default Unknown::unknown() {
                         IprToMiscRegIndex[ipr_index] : -1;
                 if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) ||
                     miscRegIndex >= NumInternalProcRegs)
-                        fault = new UnimplementedOpcodeFault;
+                    fault = std::make_shared<UnimplementedOpcodeFault>();
                 else
                     xc->setMiscReg(miscRegIndex, Ra);
                 if (traceData) { traceData->setData(Ra); }
@@ -929,7 +941,14 @@ decode OPCODE default Unknown::unknown() {
                 PseudoInst::arm(xc->tcBase());
             }}, IsNonSpeculative);
             0x01: quiesce({{
-                PseudoInst::quiesce(xc->tcBase());
+                // Don't sleep if (unmasked) interrupts are pending
+                Interrupts* interrupts =
+                    xc->tcBase()->getCpuPtr()->getInterruptController(0);
+                if (interrupts->checkInterrupts(xc->tcBase())) {
+                    PseudoInst::quiesceSkip(xc->tcBase());
+                } else {
+                    PseudoInst::quiesce(xc->tcBase());
+                }
             }}, IsNonSpeculative, IsQuiesce);
             0x02: quiesceNs({{
                 PseudoInst::quiesceNs(xc->tcBase(), R16);
@@ -963,7 +982,7 @@ decode OPCODE default Unknown::unknown() {
                 PseudoInst::loadsymbol(xc->tcBase());
             }}, No_OpClass, IsNonSpeculative);
             0x30: initparam({{
-                Ra = PseudoInst::initParam(xc->tcBase());
+                Ra = PseudoInst::initParam(xc->tcBase(), R16, R17);
             }});
             0x40: resetstats({{
                 PseudoInst::resetstats(xc->tcBase(), R16, R17);