1// Copyright (c) 2006 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright --- 62 unchanged lines hidden (view full) --- 71 0x0: bpcci(19, {{ 72 if(passesCondition(Ccr<3:0>, COND2)) 73 NNPC = xc->readPC() + disp; 74 else 75 handle_annul 76 }}); 77 0x2: bpccx(19, {{ 78 if(passesCondition(Ccr<7:4>, COND2)) |
79 NNPC = xc->readPC() + disp; |
80 else |
81 handle_annul |
82 }}); 83 } 84 } 85 //bicc 86 0x2: decode COND2 87 { 88 //Branch Always 89 0x8: decode A --- 152 unchanged lines hidden (view full) --- 242 int64_t carryin = Ccr<0:0>; 243 Rd = resTemp = Rs1 + val2 + carryin;}}, 244 {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}}, 245 {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, 246 {{(Rs1<63:1> + val2<63:1> + 247 ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}}, 248 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 249 ); |
250 0x1A: umulcc({{ |
251 uint64_t resTemp; 252 Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; |
253 Y = resTemp<63:32>;}}, 254 {{0}},{{0}},{{0}},{{0}}); 255 0x1B: smulcc({{ |
256 int64_t resTemp; 257 Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; |
258 Y = resTemp<63:32>;}}, 259 {{0}},{{0}},{{0}},{{0}}); |
260 0x1C: subccc({{ 261 int64_t resTemp, val2 = Rs2_or_imm13; 262 int64_t carryin = Ccr<0:0>; 263 Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}}, 264 {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}}, 265 {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, 266 {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}}, 267 {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} 268 ); |
269 0x1D: udivxcc({{ |
270 if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; |
271 else Rd = Rs1.udw / Rs2_or_imm13.udw;}} 272 ,{{0}},{{0}},{{0}},{{0}}); |
273 0x1E: udivcc({{ 274 uint32_t resTemp, val2 = Rs2_or_imm13.udw; 275 int32_t overflow = 0; 276 if(val2 == 0) fault = new DivisionByZero; 277 else 278 { 279 resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2; 280 overflow = (resTemp<63:32> != 0); --- 594 unchanged lines hidden (view full) --- 875 fault = new MemAddressNotAligned; 876 else 877 { 878 Rd = xc->readPC(); 879 NNPC = target; 880 } 881 }}); 882 0x39: Branch::return({{ |
883 //If both MemAddressNotAligned and 884 //a fill trap happen, it's not clear 885 //which one should be returned. |
886 Addr target = Rs1 + Rs2_or_imm13; |
887 if(target & 0x3) 888 fault = new MemAddressNotAligned; 889 else 890 NNPC = target; |
891 if(fault == NoFault) 892 { |
893 if(Canrestore == 0) 894 { 895 if(Otherwin) 896 fault = new FillNOther(Wstate<5:3>); 897 else 898 fault = new FillNNormal(Wstate<2:0>); 899 } |
900 else 901 { |
902 //CWP should be set directly so that it always happens 903 //Also, this will allow writing to the new window and 904 //reading from the old one |
905 Cwp = (Cwp - 1 + NWindows) % NWindows; 906 Cansave = Cansave + 1; 907 Canrestore = Canrestore - 1; |
908 //This is here to make sure the CWP is written 909 //no matter what. This ensures that the results 910 //are written in the new window as well. 911 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); |
912 } 913 } 914 }}); 915 0x3A: decode CC 916 { 917 0x0: Trap::tcci({{ 918 if(passesCondition(Ccr<3:0>, COND2)) 919 { 920#if FULL_SYSTEM 921 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 922 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 923 fault = new TrapInstruction(lTrapNum); 924#else 925 DPRINTF(Sparc, "The syscall number is %d\n", R1); 926 xc->syscall(R1); 927#endif 928 } |
929 }}); |
930 0x2: Trap::tccx({{ 931 if(passesCondition(Ccr<7:4>, COND2)) 932 { 933#if FULL_SYSTEM 934 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 935 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 936 fault = new TrapInstruction(lTrapNum); 937#else 938 DPRINTF(Sparc, "The syscall number is %d\n", R1); 939 xc->syscall(R1); 940#endif 941 } |
942 }}); |
943 } 944 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 945 0x3C: save({{ |
946 //CWP should be set directly so that it always happens 947 //Also, this will allow writing to the new window and 948 //reading from the old one |
949 if(Cansave == 0) 950 { 951 if(Otherwin) 952 fault = new SpillNOther(Wstate<5:3>); 953 else 954 fault = new SpillNNormal(Wstate<2:0>); |
955 //Cwp = (Cwp + 2) % NWindows; |
956 } 957 else if(Cleanwin - Canrestore == 0) 958 { |
959 //Cwp = (Cwp + 1) % NWindows; |
960 fault = new CleanWindow; 961 } 962 else 963 { 964 Cwp = (Cwp + 1) % NWindows; |
965 Rd = Rs1 + Rs2_or_imm13; |
966 Cansave = Cansave - 1; 967 Canrestore = Canrestore + 1; |
968 //This is here to make sure the CWP is written 969 //no matter what. This ensures that the results 970 //are written in the new window as well. 971 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); |
972 } 973 }}); 974 0x3D: restore({{ 975 if(Canrestore == 0) 976 { 977 if(Otherwin) 978 fault = new FillNOther(Wstate<5:3>); 979 else 980 fault = new FillNNormal(Wstate<2:0>); 981 } 982 else 983 { |
984 //CWP should be set directly so that it always happens 985 //Also, this will allow writing to the new window and 986 //reading from the old one |
987 Cwp = (Cwp - 1 + NWindows) % NWindows; |
988 Rd = Rs1 + Rs2_or_imm13; |
989 Cansave = Cansave + 1; 990 Canrestore = Canrestore - 1; |
991 //This is here to make sure the CWP is written 992 //no matter what. This ensures that the results 993 //are written in the new window as well. 994 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); |
995 } 996 }}); 997 0x3E: decode FCN { 998 0x0: Priv::done({{ 999 if(Tl == 0) 1000 return new IllegalInstruction; 1001 1002 Cwp = Tstate<4:0>; --- 46 unchanged lines hidden (view full) --- 1049 0x0D: LoadStore::ldstub( 1050 {{Rd = Mem.ub;}}, 1051 {{Mem.ub = 0xFF;}}); 1052 0x0E: Store::stx({{Mem.udw = Rd}}); 1053 0x0F: LoadStore::swap( 1054 {{uReg0 = Rd.uw; 1055 Rd.uw = Mem.uw;}}, 1056 {{Mem.uw = uReg0;}}); |
1057 format LoadAlt { 1058 0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}}); 1059 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); 1060 0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}}); |
1061 0x13: ldda({{ 1062 uint64_t val = Mem.udw; 1063 RdLow = val<31:0>; 1064 RdHigh = val<63:32>; |
1065 }}, {{EXT_ASI}}); |
1066 } |
1067 format StoreAlt { 1068 0x14: stwa({{Mem.uw = Rd;}}, {{EXT_ASI}}); 1069 0x15: stba({{Mem.ub = Rd;}}, {{EXT_ASI}}); 1070 0x16: stha({{Mem.uhw = Rd;}}, {{EXT_ASI}}); 1071 0x17: stda({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{EXT_ASI}}); |
1072 } |
1073 format LoadAlt { 1074 0x18: ldswa({{Rd = (int32_t)Mem.sw;}}, {{EXT_ASI}}); 1075 0x19: ldsba({{Rd = (int8_t)Mem.sb;}}, {{EXT_ASI}}); 1076 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}, {{EXT_ASI}}); 1077 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}}); |
1078 } |
1079 0x1D: LoadStoreAlt::ldstuba( |
1080 {{Rd = Mem.ub;}}, |
1081 {{Mem.ub = 0xFF}}, {{EXT_ASI}}); 1082 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}}); 1083 0x1F: LoadStoreAlt::swapa( |
1084 {{uReg0 = Rd.uw; 1085 Rd.uw = Mem.uw;}}, |
1086 {{Mem.uw = uReg0;}}, {{EXT_ASI}}); |
1087 format Trap { 1088 0x20: Load::ldf({{Frd.uw = Mem.uw;}}); 1089 0x21: decode X { 1090 0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}}); 1091 0x1: Load::ldxfsr({{Fsr = Mem.udw;}}); 1092 } 1093 0x22: ldqf({{fault = new FpDisabled;}}); 1094 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 1095 0x24: Store::stf({{Mem.uw = Frd.uw;}}); 1096 0x25: decode X { 1097 0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}}); 1098 0x1: Store::stxfsr({{Mem.udw = Fsr;}}); 1099 } 1100 0x26: stqf({{fault = new FpDisabled;}}); 1101 0x27: Store::stdf({{Mem.udw = Frd.udw;}}); 1102 0x2D: Nop::prefetch({{ }}); |
1103 0x30: LoadAlt::ldfa({{Frd.uw = Mem.uw;}}, {{EXT_ASI}}); |
1104 0x32: ldqfa({{fault = new FpDisabled;}}); 1105 format LoadAlt { 1106 0x33: decode EXT_ASI { 1107 //ASI_NUCLEUS 1108 0x04: FailUnimpl::lddfa_n(); 1109 //ASI_NUCLEUS_LITTLE 1110 0x0C: FailUnimpl::lddfa_nl(); 1111 //ASI_AS_IF_USER_PRIMARY --- 35 unchanged lines hidden (view full) --- 1147 0x16: FailUnimpl::ldblockf_aiup(); 1148 //ASI_BLOCK_AS_IF_USER_SECONDARY 1149 0x17: FailUnimpl::ldblockf_aius(); 1150 //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 1151 0x1E: FailUnimpl::ldblockf_aiupl(); 1152 //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 1153 0x1F: FailUnimpl::ldblockf_aiusl(); 1154 //ASI_BLOCK_PRIMARY |
1155 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}}, {{EXT_ASI}}); |
1156 //ASI_BLOCK_SECONDARY 1157 0xF1: FailUnimpl::ldblockf_s(); 1158 //ASI_BLOCK_PRIMARY_LITTLE 1159 0xF8: FailUnimpl::ldblockf_pl(); 1160 //ASI_BLOCK_SECONDARY_LITTLE 1161 0xF9: FailUnimpl::ldblockf_sl(); 1162 } 1163 --- 66 unchanged lines hidden (view full) --- 1230 0x16: FailUnimpl::stblockf_aiup(); 1231 //ASI_BLOCK_AS_IF_USER_SECONDARY 1232 0x17: FailUnimpl::stblockf_aius(); 1233 //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 1234 0x1E: FailUnimpl::stblockf_aiupl(); 1235 //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 1236 0x1F: FailUnimpl::stblockf_aiusl(); 1237 //ASI_BLOCK_PRIMARY |
1238 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}}, {{EXT_ASI}}); |
1239 //ASI_BLOCK_SECONDARY 1240 0xF1: FailUnimpl::stblockf_s(); 1241 //ASI_BLOCK_PRIMARY_LITTLE 1242 0xF8: FailUnimpl::stblockf_pl(); 1243 //ASI_BLOCK_SECONDARY_LITTLE 1244 0xF9: FailUnimpl::stblockf_sl(); 1245 } 1246 --- 20 unchanged lines hidden (view full) --- 1267 } 1268 } 1269 0x3C: Cas::casa( 1270 {{uReg0 = Mem.uw;}}, 1271 {{if(Rs2.uw == uReg0) 1272 Mem.uw = Rd.uw; 1273 else 1274 storeCond = false; |
1275 Rd.uw = uReg0;}}, {{EXT_ASI}}); |
1276 0x3D: Nop::prefetcha({{ }}); 1277 0x3E: Cas::casxa( 1278 {{uReg0 = Mem.udw;}}, 1279 {{if(Rs2 == uReg0) 1280 Mem.udw = Rd; 1281 else 1282 storeCond = false; |
1283 Rd = uReg0;}}, {{EXT_ASI}}); |
1284 } 1285 } 1286} |