1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2013,2016-2018 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, miscReg, iss); 181 } else { 182 return new Mcr14(machInst, 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_IMPDEF_UNIMPL: 223 224 if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 225 auto mnemonic = 226 csprintf("miscreg crn:%d opc1:%d crm:%d opc2:%d %s", 227 crn, opc1, crm, opc2, isRead ? "read" : "write"); 228 229 return new WarnUnimplemented( 230 isRead ? "mrc implementation defined" : 231 "mcr implementation defined", 232 machInst, mnemonic + " treated as NOP"); 233 } else { 234 return new McrMrcImplDefined( 235 isRead ? "mrc implementation defined" : 236 "mcr implementation defined", 237 machInst, iss, MISCREG_IMPDEF_UNIMPL); 238 } 239 case MISCREG_CP15ISB: 240 return new Isb(machInst, iss); 241 case MISCREG_CP15DSB: 242 return new Dsb(machInst, iss); 243 case MISCREG_CP15DMB: 244 return new Dmb(machInst, iss); 245 case MISCREG_DCIMVAC: 246 return new McrDcimvac(machInst, miscReg, rt, iss); 247 case MISCREG_DCCMVAC: 248 return new McrDccmvac(machInst, miscReg, rt, iss); 249 case MISCREG_DCCMVAU: 250 return new McrDccmvau(machInst, miscReg, rt, iss); 251 case MISCREG_DCCIMVAC: 252 return new McrDccimvac(machInst, miscReg, rt, iss); 253 default: 254 if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 255 std::string full_mnem = csprintf("%s %s", 256 isRead ? "mrc" : "mcr", miscRegName[miscReg]); 257 warn("\\tinstruction '%s' unimplemented\\n", full_mnem); 258 259 // Remove the warn flag and set the implemented flag. This 260 // prevents the instruction warning a second time, it also 261 // means the instruction is actually generated. Actually 262 // creating the instruction to access an register that isn't 263 // implemented sounds a bit silly, but its required to get 264 // the correct behaviour for hyp traps and undef exceptions. 265 miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true; 266 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false; 267 } 268 269 if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 270 if (isRead) 271 return new Mrc15(machInst, rt, miscReg, iss); 272 return new Mcr15(machInst, miscReg, rt, iss); 273 } else { 274 return new FailUnimplemented(isRead ? "mrc" : "mcr", machInst, 275 csprintf("%s %s", isRead ? "mrc" : "mcr", 276 miscRegName[miscReg])); 277 } 278 } 279 } 280 ''' 281}}; 282 283def format McrMrc15() {{ 284 decode_block = ''' 285 return decodeMcrMrc15(machInst); 286 ''' 287}}; 288 289let {{ 290 header_output = ''' 291 StaticInstPtr 292 decodeMcrrMrrc15(ExtMachInst machInst); 293 ''' 294 decoder_output = ''' 295 StaticInstPtr 296 decodeMcrrMrrc15(ExtMachInst machInst) 297 { 298 const uint32_t crm = bits(machInst, 3, 0); 299 const uint32_t opc1 = bits(machInst, 7, 4); 300 const MiscRegIndex miscReg = decodeCP15Reg64(crm, opc1); 301 const IntRegIndex rt = (IntRegIndex) (uint32_t) bits(machInst, 15, 12); 302 const IntRegIndex rt2 = (IntRegIndex) (uint32_t) bits(machInst, 19, 16); 303 304 const bool isRead = bits(machInst, 20); 305 306 switch (miscReg) { 307 case MISCREG_CP15_UNIMPL: 308 return new FailUnimplemented(isRead ? "mrc" : "mcr", machInst, 309 csprintf("miscreg crm:%d opc1:%d 64-bit %s unknown", 310 crm, opc1, isRead ? "read" : "write")); 311 default: 312 if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 313 std::string full_mnem = csprintf("%s %s", 314 isRead ? "mrrc" : "mcrr", miscRegName[miscReg]); 315 warn("\\tinstruction '%s' unimplemented\\n", full_mnem); 316 317 // Remove the warn flag and set the implemented flag. This 318 // prevents the instruction warning a second time, it also 319 // means the instruction is actually generated. Actually 320 // creating the instruction to access an register that isn't 321 // implemented sounds a bit silly, but its required to get 322 // the correct behaviour for hyp traps and undef exceptions. 323 miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true; 324 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false; 325 } 326 327 if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 328 uint32_t iss = mcrrMrrcIssBuild(isRead, crm, rt, rt2, opc1); 329 330 if (isRead) { 331 StaticInstPtr si = new Mrrc15(machInst, miscReg, rt2, rt, iss); 332 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 333 si->setFlag(StaticInst::IsUnverifiable); 334 return si; 335 } 336 return new Mcrr15(machInst, rt2, rt, miscReg, iss); 337 } else { 338 return new FailUnimplemented(isRead ? "mrrc" : "mcrr", machInst, 339 csprintf("%s %s", 340 isRead ? "mrrc" : "mcrr", miscRegName[miscReg])); 341 } 342 } 343 } 344 ''' 345}}; 346 347def format Mcrr15() {{ 348 decode_block = ''' 349 return decodeMcrrMrrc15(machInst); 350 ''' 351}}; 352 353def format Mrrc15() {{ 354 decode_block = ''' 355 return decodeMcrrMrrc15(machInst); 356 ''' 357}}; 358