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