misc.isa revision 12358:386d26feb00f
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2013,2016-2017 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39// Giacomo Gabrielli 40 41def format Crc32() {{ 42 decode_block = ''' 43 { 44 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 45 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 46 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 47 48 uint8_t c_poly = bits(machInst, 9); 49 uint8_t sz = bits(machInst, 22, 21); 50 uint8_t crc_select = (c_poly << 2) | sz; 51 52 switch(crc_select) { 53 case 0x0: 54 return new Crc32b(machInst, rd, rn, rm); 55 case 0x1: 56 return new Crc32h(machInst, rd, rn, rm); 57 case 0x2: 58 return new Crc32w(machInst, rd, rn, rm); 59 case 0x4: 60 return new Crc32cb(machInst, rd, rn, rm); 61 case 0x5: 62 return new Crc32ch(machInst, rd, rn, rm); 63 case 0x6: 64 return new Crc32cw(machInst, rd, rn, rm); 65 default: 66 return new Unknown(machInst); 67 } 68 } 69 ''' 70}}; 71 72def format ArmERet() {{ 73 decode_block = "return new Eret(machInst);" 74}}; 75 76def format Svc() {{ 77 decode_block = "return new Svc(machInst, bits(machInst, 23, 0));" 78}}; 79 80def format ArmSmcHyp() {{ 81 decode_block = ''' 82 { 83 if (bits(machInst, 21)) 84 { 85 return new Smc(machInst); 86 } else { 87 uint32_t imm16 = (bits(machInst, 19, 8) << 4) | 88 (bits(machInst, 3, 0) << 0); 89 return new Hvc(machInst, imm16); 90 } 91 } 92 ''' 93}}; 94 95def format ArmMsrMrs() {{ 96 decode_block = ''' 97 { 98 const uint8_t byteMask = bits(machInst, 19, 16); 99 const uint8_t sysM = byteMask | (bits(machInst, 8) << 4); 100 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 101 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 102 const uint32_t opcode = bits(machInst, 24, 21); 103 const bool useImm = bits(machInst, 25); 104 const bool r = bits(machInst, 22); 105 const bool isBanked = bits(machInst, 9); 106 107 const uint32_t unrotated = bits(machInst, 7, 0); 108 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 109 const uint32_t imm = rotate_imm(unrotated, rotation); 110 111 switch (opcode) { 112 case 0x8: 113 if (isBanked) { 114 return new MrsBankedReg(machInst, rd, sysM, r!=0); 115 } else { 116 return new MrsCpsr(machInst, rd); 117 } 118 case 0x9: 119 if (useImm) { 120 return new MsrCpsrImm(machInst, imm, byteMask); 121 } else { 122 if (isBanked) { 123 return new MsrBankedReg(machInst, rn, sysM, r!=0); 124 } else { 125 return new MsrCpsrReg(machInst, rn, byteMask); 126 } 127 } 128 case 0xa: 129 if (isBanked) { 130 return new MrsBankedReg(machInst, rd, sysM, r!=0); 131 } else { 132 return new MrsSpsr(machInst, rd); 133 } 134 case 0xb: 135 if (useImm) { 136 return new MsrSpsrImm(machInst, imm, byteMask); 137 } else { 138 if (isBanked) { 139 return new MsrBankedReg(machInst, rn, sysM, r!=0); 140 } else { 141 return new MsrSpsrReg(machInst, rn, byteMask); 142 } 143 } 144 default: 145 return new Unknown(machInst); 146 } 147 } 148 ''' 149}}; 150 151let {{ 152 header_output = ''' 153 StaticInstPtr 154 decodeMcrMrc14(ExtMachInst machInst); 155 ''' 156 decoder_output = ''' 157 StaticInstPtr 158 decodeMcrMrc14(ExtMachInst machInst) 159 { 160 const uint32_t opc1 = bits(machInst, 23, 21); 161 const uint32_t crn = bits(machInst, 19, 16); 162 const uint32_t opc2 = bits(machInst, 7, 5); 163 const uint32_t crm = bits(machInst, 3, 0); 164 const MiscRegIndex miscReg = decodeCP14Reg(crn, opc1, crm, opc2); 165 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 166 167 const bool isRead = bits(machInst, 20); 168 169 switch (miscReg) { 170 case MISCREG_NOP: 171 return new NopInst(machInst); 172 case MISCREG_CP14_UNIMPL: 173 return new FailUnimplemented(isRead ? "mrc unknown" : "mcr unknown", 174 machInst, 175 csprintf("miscreg crn:%d opc1:%d crm:%d opc2:%d %s unknown", 176 crn, opc1, crm, opc2, isRead ? "read" : "write")); 177 default: 178 uint32_t iss = mcrMrcIssBuild(isRead, crm, rt, crn, opc1, opc2); 179 if (isRead) { 180 return new Mrc14(machInst, rt, (IntRegIndex)miscReg, iss); 181 } else { 182 return new Mcr14(machInst, (IntRegIndex)miscReg, rt, iss); 183 } 184 } 185 } 186 ''' 187}}; 188 189def format McrMrc14() {{ 190 decode_block = ''' 191 return decodeMcrMrc14(machInst); 192 ''' 193}}; 194 195let {{ 196 header_output = ''' 197 StaticInstPtr decodeMcrMrc14(ExtMachInst machInst); 198 StaticInstPtr decodeMcrMrc15(ExtMachInst machInst); 199 ''' 200 decoder_output = ''' 201 StaticInstPtr 202 decodeMcrMrc15(ExtMachInst machInst) 203 { 204 const uint32_t opc1 = bits(machInst, 23, 21); 205 const uint32_t crn = bits(machInst, 19, 16); 206 const uint32_t opc2 = bits(machInst, 7, 5); 207 const uint32_t crm = bits(machInst, 3, 0); 208 const MiscRegIndex miscReg = decodeCP15Reg(crn, opc1, crm, opc2); 209 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 210 const bool isRead = bits(machInst, 20); 211 uint32_t iss = mcrMrcIssBuild(isRead, crm, rt, crn, opc1, opc2); 212 213 switch (miscReg) { 214 case MISCREG_NOP: 215 return new McrMrcMiscInst(isRead ? "mrc nop" : "mcr nop", 216 machInst, iss, MISCREG_NOP); 217 case MISCREG_CP15_UNIMPL: 218 return new FailUnimplemented(isRead ? "mrc unkown" : "mcr unkown", 219 machInst, 220 csprintf("miscreg crn:%d opc1:%d crm:%d opc2:%d %s unknown", 221 crn, opc1, crm, opc2, isRead ? "read" : "write")); 222 case MISCREG_CP15ISB: 223 return new Isb(machInst, iss); 224 case MISCREG_CP15DSB: 225 return new Dsb(machInst, iss); 226 case MISCREG_CP15DMB: 227 return new Dmb(machInst, iss); 228 case MISCREG_DCIMVAC: 229 return new McrDcimvac(machInst, miscReg, rt, iss); 230 case MISCREG_DCCMVAC: 231 return new McrDccmvac(machInst, miscReg, rt, iss); 232 case MISCREG_DCCMVAU: 233 return new McrDccmvau(machInst, miscReg, rt, iss); 234 case MISCREG_DCCIMVAC: 235 return new McrDccimvac(machInst, miscReg, rt, iss); 236 default: 237 if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 238 std::string full_mnem = csprintf("%s %s", 239 isRead ? "mrc" : "mcr", miscRegName[miscReg]); 240 warn("\\tinstruction '%s' unimplemented\\n", full_mnem); 241 242 // Remove the warn flag and set the implemented flag. This 243 // prevents the instruction warning a second time, it also 244 // means the instruction is actually generated. Actually 245 // creating the instruction to access an register that isn't 246 // implemented sounds a bit silly, but its required to get 247 // the correct behaviour for hyp traps and undef exceptions. 248 miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true; 249 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false; 250 } 251 252 if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 253 if (isRead) 254 return new Mrc15(machInst, rt, miscReg, iss); 255 return new Mcr15(machInst, miscReg, rt, iss); 256 } else { 257 return new FailUnimplemented(isRead ? "mrc" : "mcr", machInst, 258 csprintf("%s %s", isRead ? "mrc" : "mcr", 259 miscRegName[miscReg])); 260 } 261 } 262 } 263 ''' 264}}; 265 266def format McrMrc15() {{ 267 decode_block = ''' 268 return decodeMcrMrc15(machInst); 269 ''' 270}}; 271 272let {{ 273 header_output = ''' 274 StaticInstPtr 275 decodeMcrrMrrc15(ExtMachInst machInst); 276 ''' 277 decoder_output = ''' 278 StaticInstPtr 279 decodeMcrrMrrc15(ExtMachInst machInst) 280 { 281 const uint32_t crm = bits(machInst, 3, 0); 282 const uint32_t opc1 = bits(machInst, 7, 4); 283 const MiscRegIndex miscReg = decodeCP15Reg64(crm, opc1); 284 const IntRegIndex rt = (IntRegIndex) (uint32_t) bits(machInst, 15, 12); 285 const IntRegIndex rt2 = (IntRegIndex) (uint32_t) bits(machInst, 19, 16); 286 287 const bool isRead = bits(machInst, 20); 288 289 switch (miscReg) { 290 case MISCREG_CP15_UNIMPL: 291 return new FailUnimplemented(isRead ? "mrc" : "mcr", machInst, 292 csprintf("miscreg crm:%d opc1:%d 64-bit %s unknown", 293 crm, opc1, isRead ? "read" : "write")); 294 default: 295 if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 296 std::string full_mnem = csprintf("%s %s", 297 isRead ? "mrrc" : "mcrr", miscRegName[miscReg]); 298 warn("\\tinstruction '%s' unimplemented\\n", full_mnem); 299 300 // Remove the warn flag and set the implemented flag. This 301 // prevents the instruction warning a second time, it also 302 // means the instruction is actually generated. Actually 303 // creating the instruction to access an register that isn't 304 // implemented sounds a bit silly, but its required to get 305 // the correct behaviour for hyp traps and undef exceptions. 306 miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true; 307 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false; 308 } 309 310 if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 311 uint32_t iss = mcrrMrrcIssBuild(isRead, crm, rt, rt2, opc1); 312 313 if (isRead) { 314 StaticInstPtr si = new Mrrc15(machInst, miscReg, rt2, rt, iss); 315 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 316 si->setFlag(StaticInst::IsUnverifiable); 317 return si; 318 } 319 return new Mcrr15(machInst, rt2, rt, miscReg, iss); 320 } else { 321 return new FailUnimplemented(isRead ? "mrrc" : "mcrr", machInst, 322 csprintf("%s %s", 323 isRead ? "mrrc" : "mcrr", miscRegName[miscReg])); 324 } 325 } 326 } 327 ''' 328}}; 329 330def format Mcrr15() {{ 331 decode_block = ''' 332 return decodeMcrrMrrc15(machInst); 333 ''' 334}}; 335 336def format Mrrc15() {{ 337 decode_block = ''' 338 return decodeMcrrMrrc15(machInst); 339 ''' 340}}; 341