1// Copyright (c) 2010 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Gabe Black 37 38def format ArmDataProcReg() {{ 39 pclr = ''' 40 return new %(className)ssRegPclr(machInst, %(dest)s, 41 %(op1)s, rm, imm5, 42 type); 43 ''' 44 instDecode = ''' 45 case %(opcode)#x: 46 if (immShift) { 47 if (setCc) { 48 if (%(dest)s == INTREG_PC) { 49 %(pclr)s 50 } else { 51 return new %(className)sRegCc(machInst, %(dest)s, 52 %(op1)s, rm, imm5, type); 53 } 54 } else { 55 return new %(className)sReg(machInst, %(dest)s, %(op1)s, 56 rm, imm5, type); 57 } 58 } else { 59 if (setCc) { 60 return new %(className)sRegRegCc(machInst, %(dest)s, 61 %(op1)s, rm, rs, type); 62 } else { 63 return new %(className)sRegReg(machInst, %(dest)s, 64 %(op1)s, rm, rs, type); 65 } 66 } 67 break; 68 ''' 69 70 def instCode(opcode, mnem, useDest = True, useOp1 = True): 71 global pclr 72 if useDest: 73 dest = "rd" 74 else: 75 dest = "INTREG_ZERO" 76 if useOp1: 77 op1 = "rn" 78 else: 79 op1 = "INTREG_ZERO" 80 global instDecode, pclrCode 81 substDict = { "className": mnem.capitalize(), 82 "opcode": opcode, 83 "dest": dest, 84 "op1": op1 } 85 if useDest: 86 substDict["pclr"] = pclr % substDict 87 else: 88 substDict["pclr"] = "" 89 return instDecode % substDict 90 91 decode_block = ''' 92 { 93 const bool immShift = (bits(machInst, 4) == 0); 94 const bool setCc = (bits(machInst, 20) == 1); 95 const uint32_t imm5 = bits(machInst, 11, 7); 96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM; 100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS; 101 switch (OPCODE) { 102 ''' 103 decode_block += instCode(0x0, "and") 104 decode_block += instCode(0x1, "eor") 105 decode_block += instCode(0x2, "sub") 106 decode_block += instCode(0x3, "rsb") 107 decode_block += instCode(0x4, "add") 108 decode_block += instCode(0x5, "adc") 109 decode_block += instCode(0x6, "sbc") 110 decode_block += instCode(0x7, "rsc") 111 decode_block += instCode(0x8, "tst", useDest = False) 112 decode_block += instCode(0x9, "teq", useDest = False) 113 decode_block += instCode(0xa, "cmp", useDest = False) 114 decode_block += instCode(0xb, "cmn", useDest = False) 115 decode_block += instCode(0xc, "orr") 116 decode_block += instCode(0xd, "mov", useOp1 = False) 117 decode_block += instCode(0xe, "bic") 118 decode_block += instCode(0xf, "mvn", useOp1 = False) 119 decode_block += ''' 120 default: 121 return new Unknown(machInst); 122 } 123 } 124 ''' 125}}; 126 127def format ArmPackUnpackSatReverse() {{ 128 decode_block = ''' 129 { 130 const uint32_t op1 = bits(machInst, 22, 20); 131 const uint32_t a = bits(machInst, 19, 16); 132 const uint32_t op2 = bits(machInst, 7, 5); 133 if (bits(op2, 0) == 0) { 134 const IntRegIndex rn = 135 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 136 const IntRegIndex rd = 137 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 138 const uint32_t satImm = bits(machInst, 20, 16); 139 const uint32_t imm = bits(machInst, 11, 7); 140 const ArmShiftType type = 141 (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 142 if (op1 == 0) { 143 if (type) { 144 return new PkhtbReg(machInst, rd, (IntRegIndex)a, 145 rn, imm, type); 146 } else { 147 return new PkhbtReg(machInst, rd, (IntRegIndex)a, 148 rn, imm, type); 149 } 150 } else if (bits(op1, 2, 1) == 1) { 151 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 152 } else if (bits(op1, 2, 1) == 3) { 153 return new Usat(machInst, rd, satImm, rn, imm, type); 154 } 155 return new Unknown(machInst); 156 } 157 switch (op1) { 158 case 0x0:
| 1// Copyright (c) 2010 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Gabe Black 37 38def format ArmDataProcReg() {{ 39 pclr = ''' 40 return new %(className)ssRegPclr(machInst, %(dest)s, 41 %(op1)s, rm, imm5, 42 type); 43 ''' 44 instDecode = ''' 45 case %(opcode)#x: 46 if (immShift) { 47 if (setCc) { 48 if (%(dest)s == INTREG_PC) { 49 %(pclr)s 50 } else { 51 return new %(className)sRegCc(machInst, %(dest)s, 52 %(op1)s, rm, imm5, type); 53 } 54 } else { 55 return new %(className)sReg(machInst, %(dest)s, %(op1)s, 56 rm, imm5, type); 57 } 58 } else { 59 if (setCc) { 60 return new %(className)sRegRegCc(machInst, %(dest)s, 61 %(op1)s, rm, rs, type); 62 } else { 63 return new %(className)sRegReg(machInst, %(dest)s, 64 %(op1)s, rm, rs, type); 65 } 66 } 67 break; 68 ''' 69 70 def instCode(opcode, mnem, useDest = True, useOp1 = True): 71 global pclr 72 if useDest: 73 dest = "rd" 74 else: 75 dest = "INTREG_ZERO" 76 if useOp1: 77 op1 = "rn" 78 else: 79 op1 = "INTREG_ZERO" 80 global instDecode, pclrCode 81 substDict = { "className": mnem.capitalize(), 82 "opcode": opcode, 83 "dest": dest, 84 "op1": op1 } 85 if useDest: 86 substDict["pclr"] = pclr % substDict 87 else: 88 substDict["pclr"] = "" 89 return instDecode % substDict 90 91 decode_block = ''' 92 { 93 const bool immShift = (bits(machInst, 4) == 0); 94 const bool setCc = (bits(machInst, 20) == 1); 95 const uint32_t imm5 = bits(machInst, 11, 7); 96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM; 100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS; 101 switch (OPCODE) { 102 ''' 103 decode_block += instCode(0x0, "and") 104 decode_block += instCode(0x1, "eor") 105 decode_block += instCode(0x2, "sub") 106 decode_block += instCode(0x3, "rsb") 107 decode_block += instCode(0x4, "add") 108 decode_block += instCode(0x5, "adc") 109 decode_block += instCode(0x6, "sbc") 110 decode_block += instCode(0x7, "rsc") 111 decode_block += instCode(0x8, "tst", useDest = False) 112 decode_block += instCode(0x9, "teq", useDest = False) 113 decode_block += instCode(0xa, "cmp", useDest = False) 114 decode_block += instCode(0xb, "cmn", useDest = False) 115 decode_block += instCode(0xc, "orr") 116 decode_block += instCode(0xd, "mov", useOp1 = False) 117 decode_block += instCode(0xe, "bic") 118 decode_block += instCode(0xf, "mvn", useOp1 = False) 119 decode_block += ''' 120 default: 121 return new Unknown(machInst); 122 } 123 } 124 ''' 125}}; 126 127def format ArmPackUnpackSatReverse() {{ 128 decode_block = ''' 129 { 130 const uint32_t op1 = bits(machInst, 22, 20); 131 const uint32_t a = bits(machInst, 19, 16); 132 const uint32_t op2 = bits(machInst, 7, 5); 133 if (bits(op2, 0) == 0) { 134 const IntRegIndex rn = 135 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 136 const IntRegIndex rd = 137 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 138 const uint32_t satImm = bits(machInst, 20, 16); 139 const uint32_t imm = bits(machInst, 11, 7); 140 const ArmShiftType type = 141 (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 142 if (op1 == 0) { 143 if (type) { 144 return new PkhtbReg(machInst, rd, (IntRegIndex)a, 145 rn, imm, type); 146 } else { 147 return new PkhbtReg(machInst, rd, (IntRegIndex)a, 148 rn, imm, type); 149 } 150 } else if (bits(op1, 2, 1) == 1) { 151 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 152 } else if (bits(op1, 2, 1) == 3) { 153 return new Usat(machInst, rd, satImm, rn, imm, type); 154 } 155 return new Unknown(machInst); 156 } 157 switch (op1) { 158 case 0x0:
|
159 if (op2 == 0x3) {
| 159 {
|
160 const IntRegIndex rn = 161 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 162 const IntRegIndex rd = 163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 164 const IntRegIndex rm = 165 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
| 160 const IntRegIndex rn = 161 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 162 const IntRegIndex rd = 163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 164 const IntRegIndex rm = 165 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
|
166 const uint32_t rotation = 167 (uint32_t)bits(machInst, 11, 10) << 3; 168 if (a == 0xf) { 169 return new Sxtb16(machInst, rd, rotation, rm); 170 } else { 171 return new Sxtab16(machInst, rd, rn, rm, rotation);
| 166 if (op2 == 0x3) { 167 const uint32_t rotation = 168 (uint32_t)bits(machInst, 11, 10) << 3; 169 if (a == 0xf) { 170 return new Sxtb16(machInst, rd, rotation, rm); 171 } else { 172 return new Sxtab16(machInst, rd, rn, rm, rotation); 173 } 174 } else if (op2 == 0x5) { 175 return new Sel(machInst, rd, rn, rm);
|
172 }
| 176 }
|
173 } else if (op2 == 0x5) { 174 return new WarnUnimplemented("sel", machInst);
| |
175 } 176 break; 177 case 0x2: 178 if (op2 == 0x1) { 179 const IntRegIndex rn = 180 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 181 const IntRegIndex rd = 182 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 183 const uint32_t satImm = bits(machInst, 20, 16); 184 return new Ssat16(machInst, rd, satImm + 1, rn); 185 } else if (op2 == 0x3) { 186 const IntRegIndex rn = 187 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 188 const IntRegIndex rd = 189 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 190 const IntRegIndex rm = 191 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 192 const uint32_t rotation = 193 (uint32_t)bits(machInst, 11, 10) << 3; 194 if (a == 0xf) { 195 return new Sxtb(machInst, rd, rotation, rm); 196 } else { 197 return new Sxtab(machInst, rd, rn, rm, rotation); 198 } 199 } 200 break; 201 case 0x3: 202 if (op2 == 0x1) { 203 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 204 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 205 return new Rev(machInst, rd, rm); 206 } else if (op2 == 0x3) { 207 const IntRegIndex rn = 208 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 209 const IntRegIndex rd = 210 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 211 const IntRegIndex rm = 212 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 213 const uint32_t rotation = 214 (uint32_t)bits(machInst, 11, 10) << 3; 215 if (a == 0xf) { 216 return new Sxth(machInst, rd, rotation, rm); 217 } else { 218 return new Sxtah(machInst, rd, rn, rm, rotation); 219 } 220 } else if (op2 == 0x5) { 221 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 222 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 223 return new Rev16(machInst, rd, rm); 224 } 225 break; 226 case 0x4: 227 if (op2 == 0x3) { 228 const IntRegIndex rn = 229 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 230 const IntRegIndex rd = 231 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 232 const IntRegIndex rm = 233 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 234 const uint32_t rotation = 235 (uint32_t)bits(machInst, 11, 10) << 3; 236 if (a == 0xf) { 237 return new Uxtb16(machInst, rd, rotation, rm); 238 } else { 239 return new Uxtab16(machInst, rd, rn, rm, rotation); 240 } 241 } 242 break; 243 case 0x6: 244 if (op2 == 0x1) { 245 const IntRegIndex rn = 246 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 247 const IntRegIndex rd = 248 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 249 const uint32_t satImm = bits(machInst, 20, 16); 250 return new Usat16(machInst, rd, satImm, rn); 251 } else if (op2 == 0x3) { 252 const IntRegIndex rn = 253 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 254 const IntRegIndex rd = 255 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 256 const IntRegIndex rm = 257 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 258 const uint32_t rotation = 259 (uint32_t)bits(machInst, 11, 10) << 3; 260 if (a == 0xf) { 261 return new Uxtb(machInst, rd, rotation, rm); 262 } else { 263 return new Uxtab(machInst, rd, rn, rm, rotation); 264 } 265 } 266 break; 267 case 0x7: 268 if (op2 == 0x1) { 269 return new WarnUnimplemented("rbit", machInst); 270 } else if (op2 == 0x3) { 271 const IntRegIndex rn = 272 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 273 const IntRegIndex rd = 274 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 275 const IntRegIndex rm = 276 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 277 const uint32_t rotation = 278 (uint32_t)bits(machInst, 11, 10) << 3; 279 if (a == 0xf) { 280 return new Uxth(machInst, rd, rotation, rm); 281 } else { 282 return new Uxtah(machInst, rd, rn, rm, rotation); 283 } 284 } else if (op2 == 0x5) { 285 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 286 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 287 return new Revsh(machInst, rd, rm); 288 } 289 break; 290 } 291 return new Unknown(machInst); 292 } 293 ''' 294}}; 295 296def format ArmParallelAddSubtract() {{ 297 decode_block=''' 298 { 299 const uint32_t op1 = bits(machInst, 21, 20); 300 const uint32_t op2 = bits(machInst, 7, 5); 301 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 302 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 303 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 304 if (bits(machInst, 22) == 0) { 305 switch (op1) { 306 case 0x1: 307 switch (op2) { 308 case 0x0: 309 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL); 310 case 0x1: 311 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL); 312 case 0x2: 313 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL); 314 case 0x3: 315 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL); 316 case 0x4: 317 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL); 318 case 0x7: 319 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL); 320 } 321 break; 322 case 0x2: 323 switch (op2) { 324 case 0x0: 325 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 326 case 0x1: 327 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 328 case 0x2: 329 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 330 case 0x3: 331 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 332 case 0x4: 333 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 334 case 0x7: 335 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 336 } 337 break; 338 case 0x3: 339 switch (op2) { 340 case 0x0: 341 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 342 case 0x1: 343 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 344 case 0x2: 345 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 346 case 0x3: 347 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 348 case 0x4: 349 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 350 case 0x7: 351 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 352 } 353 break; 354 } 355 } else { 356 switch (op1) { 357 case 0x1: 358 switch (op2) { 359 case 0x0: 360 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL); 361 case 0x1: 362 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL); 363 case 0x2: 364 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL); 365 case 0x3: 366 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL); 367 case 0x4: 368 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL); 369 case 0x7: 370 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL); 371 } 372 break; 373 case 0x2: 374 switch (op2) { 375 case 0x0: 376 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 377 case 0x1: 378 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 379 case 0x2: 380 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 381 case 0x3: 382 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 383 case 0x4: 384 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 385 case 0x7: 386 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 387 } 388 break; 389 case 0x3: 390 switch (op2) { 391 case 0x0: 392 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 393 case 0x1: 394 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 395 case 0x2: 396 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 397 case 0x3: 398 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 399 case 0x4: 400 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 401 case 0x7: 402 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 403 } 404 break; 405 } 406 } 407 return new Unknown(machInst); 408 } 409 ''' 410}}; 411 412def format ArmDataProcImm() {{ 413 pclr = ''' 414 return new %(className)ssImmPclr(machInst, %(dest)s, 415 %(op1)s, imm, false); 416 ''' 417 adr = ''' 418 return new AdrImm(machInst, %(dest)s, %(add)s, 419 imm, false); 420 ''' 421 instDecode = ''' 422 case %(opcode)#x: 423 if (setCc) { 424 if (%(pclrInst)s && %(dest)s == INTREG_PC) { 425 %(pclr)s 426 } else { 427 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s, 428 imm, rotC); 429 } 430 } else { 431 if (%(adrInst)s && %(op1)s == INTREG_PC) { 432 %(adr)s 433 } else { 434 return new %(className)sImm(machInst, %(dest)s, %(op1)s, 435 imm, rotC); 436 } 437 } 438 break; 439 ''' 440 441 def instCode(opcode, mnem, useDest = True, useOp1 = True): 442 global instDecode, pclr, adr 443 if useDest: 444 dest = "rd" 445 else: 446 dest = "INTREG_ZERO" 447 if useOp1: 448 op1 = "rn" 449 else: 450 op1 = "INTREG_ZERO" 451 substDict = { "className": mnem.capitalize(), 452 "opcode": opcode, 453 "dest": dest, 454 "op1": op1, 455 "adr": "", 456 "adrInst": "false" } 457 if useDest: 458 substDict["pclrInst"] = "true" 459 substDict["pclr"] = pclr % substDict 460 else: 461 substDict["pclrInst"] = "false" 462 substDict["pclr"] = "" 463 return instDecode % substDict 464 465 def adrCode(opcode, mnem, add="1"): 466 global instDecode, pclr, adr 467 substDict = { "className": mnem.capitalize(), 468 "opcode": opcode, 469 "dest": "rd", 470 "op1": "rn", 471 "add": add, 472 "pclrInst": "true", 473 "adrInst": "true" } 474 substDict["pclr"] = pclr % substDict 475 substDict["adr"] = adr % substDict 476 return instDecode % substDict 477 478 decode_block = ''' 479 { 480 const bool setCc = (bits(machInst, 20) == 1); 481 const uint32_t unrotated = bits(machInst, 7, 0); 482 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 483 const bool rotC = (rotation != 0); 484 const uint32_t imm = rotate_imm(unrotated, rotation); 485 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 486 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 487 switch (OPCODE) { 488 ''' 489 decode_block += instCode(0x0, "and") 490 decode_block += instCode(0x1, "eor") 491 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0") 492 decode_block += instCode(0x3, "rsb") 493 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1") 494 decode_block += instCode(0x5, "adc") 495 decode_block += instCode(0x6, "sbc") 496 decode_block += instCode(0x7, "rsc") 497 decode_block += instCode(0x8, "tst", useDest = False) 498 decode_block += instCode(0x9, "teq", useDest = False) 499 decode_block += instCode(0xa, "cmp", useDest = False) 500 decode_block += instCode(0xb, "cmn", useDest = False) 501 decode_block += instCode(0xc, "orr") 502 decode_block += instCode(0xd, "mov", useOp1 = False) 503 decode_block += instCode(0xe, "bic") 504 decode_block += instCode(0xf, "mvn", useOp1 = False) 505 decode_block += ''' 506 default: 507 return new Unknown(machInst); 508 } 509 } 510 ''' 511}}; 512 513def format ArmSatAddSub() {{ 514 decode_block = ''' 515 { 516 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 517 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 518 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 519 switch (OPCODE) { 520 case 0x8: 521 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL); 522 case 0x9: 523 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL); 524 case 0xa: 525 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL); 526 case 0xb: 527 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL); 528 default: 529 return new Unknown(machInst); 530 } 531 } 532 ''' 533}}; 534 535def format Thumb32DataProcReg() {{ 536 decode_block = ''' 537 { 538 const uint32_t op1 = bits(machInst, 23, 20); 539 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 540 const uint32_t op2 = bits(machInst, 7, 4); 541 if (bits(op1, 3) != 1) { 542 if (op2 == 0) { 543 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 544 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 545 switch (bits(op1, 2, 0)) { 546 case 0x0: 547 return new MovRegReg(machInst, rd, 548 INTREG_ZERO, rn, rm, LSL); 549 case 0x1: 550 return new MovRegRegCc(machInst, rd, 551 INTREG_ZERO, rn, rm, LSL); 552 case 0x2: 553 return new MovRegReg(machInst, rd, 554 INTREG_ZERO, rn, rm, LSR); 555 case 0x3: 556 return new MovRegRegCc(machInst, rd, 557 INTREG_ZERO, rn, rm, LSR); 558 case 0x4: 559 return new MovRegReg(machInst, rd, 560 INTREG_ZERO, rn, rm, ASR); 561 case 0x5: 562 return new MovRegRegCc(machInst, rd, 563 INTREG_ZERO, rn, rm, ASR); 564 case 0x6: 565 return new MovRegReg(machInst, rd, 566 INTREG_ZERO, rn, rm, ROR); 567 case 0x7: 568 return new MovRegRegCc(machInst, rd, 569 INTREG_ZERO, rn, rm, ROR); 570 } 571 } 572 { 573 const IntRegIndex rd = 574 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 575 const IntRegIndex rm = 576 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 577 const uint32_t rotation = 578 (uint32_t)bits(machInst, 5, 4) << 3; 579 switch (bits(op1, 2, 0)) { 580 case 0x0: 581 if (rn == 0xf) { 582 return new Sxth(machInst, rd, rotation, rm); 583 } else { 584 return new Sxtah(machInst, rd, rn, rm, rotation); 585 } 586 case 0x1: 587 if (rn == 0xf) { 588 return new Uxth(machInst, rd, rotation, rm); 589 } else { 590 return new Uxtah(machInst, rd, rn, rm, rotation); 591 } 592 case 0x2: 593 if (rn == 0xf) { 594 return new Sxtb16(machInst, rd, rotation, rm); 595 } else { 596 return new Sxtab16(machInst, rd, rn, rm, rotation); 597 } 598 case 0x3: 599 if (rn == 0xf) { 600 return new Uxtb16(machInst, rd, rotation, rm); 601 } else { 602 return new Uxtab16(machInst, rd, rn, rm, rotation); 603 } 604 case 0x4: 605 if (rn == 0xf) { 606 return new Sxtb(machInst, rd, rotation, rm); 607 } else { 608 return new Sxtab(machInst, rd, rn, rm, rotation); 609 } 610 case 0x5: 611 if (rn == 0xf) { 612 return new Uxtb(machInst, rd, rotation, rm); 613 } else { 614 return new Uxtab(machInst, rd, rn, rm, rotation); 615 } 616 default: 617 return new Unknown(machInst); 618 } 619 } 620 } else { 621 if (bits(op2, 3) == 0) { 622 const IntRegIndex rd = 623 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 624 const IntRegIndex rm = 625 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 626 if (bits(op2, 2) == 0x0) { 627 const uint32_t op1 = bits(machInst, 22, 20); 628 const uint32_t op2 = bits(machInst, 5, 4); 629 switch (op2) { 630 case 0x0: 631 switch (op1) { 632 case 0x1: 633 return new Sadd16RegCc(machInst, rd, 634 rn, rm, 0, LSL); 635 case 0x2: 636 return new SasxRegCc(machInst, rd, 637 rn, rm, 0, LSL); 638 case 0x6: 639 return new SsaxRegCc(machInst, rd, 640 rn, rm, 0, LSL); 641 case 0x5: 642 return new Ssub16RegCc(machInst, rd, 643 rn, rm, 0, LSL); 644 case 0x0: 645 return new Sadd8RegCc(machInst, rd, 646 rn, rm, 0, LSL); 647 case 0x4: 648 return new Ssub8RegCc(machInst, rd, 649 rn, rm, 0, LSL); 650 } 651 break; 652 case 0x1: 653 switch (op1) { 654 case 0x1: 655 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 656 case 0x2: 657 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 658 case 0x6: 659 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 660 case 0x5: 661 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 662 case 0x0: 663 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 664 case 0x4: 665 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 666 } 667 break; 668 case 0x2: 669 switch (op1) { 670 case 0x1: 671 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 672 case 0x2: 673 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 674 case 0x6: 675 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 676 case 0x5: 677 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 678 case 0x0: 679 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 680 case 0x4: 681 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 682 } 683 break; 684 } 685 } else { 686 const uint32_t op1 = bits(machInst, 22, 20); 687 const uint32_t op2 = bits(machInst, 5, 4); 688 switch (op2) { 689 case 0x0: 690 switch (op1) { 691 case 0x1: 692 return new Uadd16RegCc(machInst, rd, 693 rn, rm, 0, LSL); 694 case 0x2: 695 return new UasxRegCc(machInst, rd, 696 rn, rm, 0, LSL); 697 case 0x6: 698 return new UsaxRegCc(machInst, rd, 699 rn, rm, 0, LSL); 700 case 0x5: 701 return new Usub16RegCc(machInst, rd, 702 rn, rm, 0, LSL); 703 case 0x0: 704 return new Uadd8RegCc(machInst, rd, 705 rn, rm, 0, LSL); 706 case 0x4: 707 return new Usub8RegCc(machInst, rd, 708 rn, rm, 0, LSL); 709 } 710 break; 711 case 0x1: 712 switch (op1) { 713 case 0x1: 714 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 715 case 0x2: 716 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 717 case 0x6: 718 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 719 case 0x5: 720 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 721 case 0x0: 722 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 723 case 0x4: 724 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 725 } 726 break; 727 case 0x2: 728 switch (op1) { 729 case 0x1: 730 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 731 case 0x2: 732 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 733 case 0x6: 734 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 735 case 0x5: 736 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 737 case 0x0: 738 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 739 case 0x4: 740 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 741 } 742 break; 743 } 744 } 745 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) { 746 const uint32_t op1 = bits(machInst, 21, 20); 747 const uint32_t op2 = bits(machInst, 5, 4);
| 177 } 178 break; 179 case 0x2: 180 if (op2 == 0x1) { 181 const IntRegIndex rn = 182 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 183 const IntRegIndex rd = 184 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 185 const uint32_t satImm = bits(machInst, 20, 16); 186 return new Ssat16(machInst, rd, satImm + 1, rn); 187 } else if (op2 == 0x3) { 188 const IntRegIndex rn = 189 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 190 const IntRegIndex rd = 191 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 192 const IntRegIndex rm = 193 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 194 const uint32_t rotation = 195 (uint32_t)bits(machInst, 11, 10) << 3; 196 if (a == 0xf) { 197 return new Sxtb(machInst, rd, rotation, rm); 198 } else { 199 return new Sxtab(machInst, rd, rn, rm, rotation); 200 } 201 } 202 break; 203 case 0x3: 204 if (op2 == 0x1) { 205 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 206 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 207 return new Rev(machInst, rd, rm); 208 } else if (op2 == 0x3) { 209 const IntRegIndex rn = 210 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 211 const IntRegIndex rd = 212 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 213 const IntRegIndex rm = 214 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 215 const uint32_t rotation = 216 (uint32_t)bits(machInst, 11, 10) << 3; 217 if (a == 0xf) { 218 return new Sxth(machInst, rd, rotation, rm); 219 } else { 220 return new Sxtah(machInst, rd, rn, rm, rotation); 221 } 222 } else if (op2 == 0x5) { 223 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 224 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 225 return new Rev16(machInst, rd, rm); 226 } 227 break; 228 case 0x4: 229 if (op2 == 0x3) { 230 const IntRegIndex rn = 231 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 232 const IntRegIndex rd = 233 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 234 const IntRegIndex rm = 235 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 236 const uint32_t rotation = 237 (uint32_t)bits(machInst, 11, 10) << 3; 238 if (a == 0xf) { 239 return new Uxtb16(machInst, rd, rotation, rm); 240 } else { 241 return new Uxtab16(machInst, rd, rn, rm, rotation); 242 } 243 } 244 break; 245 case 0x6: 246 if (op2 == 0x1) { 247 const IntRegIndex rn = 248 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 249 const IntRegIndex rd = 250 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 251 const uint32_t satImm = bits(machInst, 20, 16); 252 return new Usat16(machInst, rd, satImm, rn); 253 } else if (op2 == 0x3) { 254 const IntRegIndex rn = 255 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 256 const IntRegIndex rd = 257 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 258 const IntRegIndex rm = 259 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 260 const uint32_t rotation = 261 (uint32_t)bits(machInst, 11, 10) << 3; 262 if (a == 0xf) { 263 return new Uxtb(machInst, rd, rotation, rm); 264 } else { 265 return new Uxtab(machInst, rd, rn, rm, rotation); 266 } 267 } 268 break; 269 case 0x7: 270 if (op2 == 0x1) { 271 return new WarnUnimplemented("rbit", machInst); 272 } else if (op2 == 0x3) { 273 const IntRegIndex rn = 274 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 275 const IntRegIndex rd = 276 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 277 const IntRegIndex rm = 278 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 279 const uint32_t rotation = 280 (uint32_t)bits(machInst, 11, 10) << 3; 281 if (a == 0xf) { 282 return new Uxth(machInst, rd, rotation, rm); 283 } else { 284 return new Uxtah(machInst, rd, rn, rm, rotation); 285 } 286 } else if (op2 == 0x5) { 287 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 288 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 289 return new Revsh(machInst, rd, rm); 290 } 291 break; 292 } 293 return new Unknown(machInst); 294 } 295 ''' 296}}; 297 298def format ArmParallelAddSubtract() {{ 299 decode_block=''' 300 { 301 const uint32_t op1 = bits(machInst, 21, 20); 302 const uint32_t op2 = bits(machInst, 7, 5); 303 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 304 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 305 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 306 if (bits(machInst, 22) == 0) { 307 switch (op1) { 308 case 0x1: 309 switch (op2) { 310 case 0x0: 311 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL); 312 case 0x1: 313 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL); 314 case 0x2: 315 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL); 316 case 0x3: 317 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL); 318 case 0x4: 319 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL); 320 case 0x7: 321 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL); 322 } 323 break; 324 case 0x2: 325 switch (op2) { 326 case 0x0: 327 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 328 case 0x1: 329 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 330 case 0x2: 331 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 332 case 0x3: 333 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 334 case 0x4: 335 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 336 case 0x7: 337 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 338 } 339 break; 340 case 0x3: 341 switch (op2) { 342 case 0x0: 343 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 344 case 0x1: 345 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 346 case 0x2: 347 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 348 case 0x3: 349 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 350 case 0x4: 351 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 352 case 0x7: 353 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 354 } 355 break; 356 } 357 } else { 358 switch (op1) { 359 case 0x1: 360 switch (op2) { 361 case 0x0: 362 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL); 363 case 0x1: 364 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL); 365 case 0x2: 366 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL); 367 case 0x3: 368 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL); 369 case 0x4: 370 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL); 371 case 0x7: 372 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL); 373 } 374 break; 375 case 0x2: 376 switch (op2) { 377 case 0x0: 378 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 379 case 0x1: 380 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 381 case 0x2: 382 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 383 case 0x3: 384 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 385 case 0x4: 386 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 387 case 0x7: 388 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 389 } 390 break; 391 case 0x3: 392 switch (op2) { 393 case 0x0: 394 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 395 case 0x1: 396 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 397 case 0x2: 398 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 399 case 0x3: 400 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 401 case 0x4: 402 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 403 case 0x7: 404 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 405 } 406 break; 407 } 408 } 409 return new Unknown(machInst); 410 } 411 ''' 412}}; 413 414def format ArmDataProcImm() {{ 415 pclr = ''' 416 return new %(className)ssImmPclr(machInst, %(dest)s, 417 %(op1)s, imm, false); 418 ''' 419 adr = ''' 420 return new AdrImm(machInst, %(dest)s, %(add)s, 421 imm, false); 422 ''' 423 instDecode = ''' 424 case %(opcode)#x: 425 if (setCc) { 426 if (%(pclrInst)s && %(dest)s == INTREG_PC) { 427 %(pclr)s 428 } else { 429 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s, 430 imm, rotC); 431 } 432 } else { 433 if (%(adrInst)s && %(op1)s == INTREG_PC) { 434 %(adr)s 435 } else { 436 return new %(className)sImm(machInst, %(dest)s, %(op1)s, 437 imm, rotC); 438 } 439 } 440 break; 441 ''' 442 443 def instCode(opcode, mnem, useDest = True, useOp1 = True): 444 global instDecode, pclr, adr 445 if useDest: 446 dest = "rd" 447 else: 448 dest = "INTREG_ZERO" 449 if useOp1: 450 op1 = "rn" 451 else: 452 op1 = "INTREG_ZERO" 453 substDict = { "className": mnem.capitalize(), 454 "opcode": opcode, 455 "dest": dest, 456 "op1": op1, 457 "adr": "", 458 "adrInst": "false" } 459 if useDest: 460 substDict["pclrInst"] = "true" 461 substDict["pclr"] = pclr % substDict 462 else: 463 substDict["pclrInst"] = "false" 464 substDict["pclr"] = "" 465 return instDecode % substDict 466 467 def adrCode(opcode, mnem, add="1"): 468 global instDecode, pclr, adr 469 substDict = { "className": mnem.capitalize(), 470 "opcode": opcode, 471 "dest": "rd", 472 "op1": "rn", 473 "add": add, 474 "pclrInst": "true", 475 "adrInst": "true" } 476 substDict["pclr"] = pclr % substDict 477 substDict["adr"] = adr % substDict 478 return instDecode % substDict 479 480 decode_block = ''' 481 { 482 const bool setCc = (bits(machInst, 20) == 1); 483 const uint32_t unrotated = bits(machInst, 7, 0); 484 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 485 const bool rotC = (rotation != 0); 486 const uint32_t imm = rotate_imm(unrotated, rotation); 487 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 488 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 489 switch (OPCODE) { 490 ''' 491 decode_block += instCode(0x0, "and") 492 decode_block += instCode(0x1, "eor") 493 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0") 494 decode_block += instCode(0x3, "rsb") 495 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1") 496 decode_block += instCode(0x5, "adc") 497 decode_block += instCode(0x6, "sbc") 498 decode_block += instCode(0x7, "rsc") 499 decode_block += instCode(0x8, "tst", useDest = False) 500 decode_block += instCode(0x9, "teq", useDest = False) 501 decode_block += instCode(0xa, "cmp", useDest = False) 502 decode_block += instCode(0xb, "cmn", useDest = False) 503 decode_block += instCode(0xc, "orr") 504 decode_block += instCode(0xd, "mov", useOp1 = False) 505 decode_block += instCode(0xe, "bic") 506 decode_block += instCode(0xf, "mvn", useOp1 = False) 507 decode_block += ''' 508 default: 509 return new Unknown(machInst); 510 } 511 } 512 ''' 513}}; 514 515def format ArmSatAddSub() {{ 516 decode_block = ''' 517 { 518 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 519 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 520 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 521 switch (OPCODE) { 522 case 0x8: 523 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL); 524 case 0x9: 525 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL); 526 case 0xa: 527 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL); 528 case 0xb: 529 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL); 530 default: 531 return new Unknown(machInst); 532 } 533 } 534 ''' 535}}; 536 537def format Thumb32DataProcReg() {{ 538 decode_block = ''' 539 { 540 const uint32_t op1 = bits(machInst, 23, 20); 541 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 542 const uint32_t op2 = bits(machInst, 7, 4); 543 if (bits(op1, 3) != 1) { 544 if (op2 == 0) { 545 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 546 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 547 switch (bits(op1, 2, 0)) { 548 case 0x0: 549 return new MovRegReg(machInst, rd, 550 INTREG_ZERO, rn, rm, LSL); 551 case 0x1: 552 return new MovRegRegCc(machInst, rd, 553 INTREG_ZERO, rn, rm, LSL); 554 case 0x2: 555 return new MovRegReg(machInst, rd, 556 INTREG_ZERO, rn, rm, LSR); 557 case 0x3: 558 return new MovRegRegCc(machInst, rd, 559 INTREG_ZERO, rn, rm, LSR); 560 case 0x4: 561 return new MovRegReg(machInst, rd, 562 INTREG_ZERO, rn, rm, ASR); 563 case 0x5: 564 return new MovRegRegCc(machInst, rd, 565 INTREG_ZERO, rn, rm, ASR); 566 case 0x6: 567 return new MovRegReg(machInst, rd, 568 INTREG_ZERO, rn, rm, ROR); 569 case 0x7: 570 return new MovRegRegCc(machInst, rd, 571 INTREG_ZERO, rn, rm, ROR); 572 } 573 } 574 { 575 const IntRegIndex rd = 576 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 577 const IntRegIndex rm = 578 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 579 const uint32_t rotation = 580 (uint32_t)bits(machInst, 5, 4) << 3; 581 switch (bits(op1, 2, 0)) { 582 case 0x0: 583 if (rn == 0xf) { 584 return new Sxth(machInst, rd, rotation, rm); 585 } else { 586 return new Sxtah(machInst, rd, rn, rm, rotation); 587 } 588 case 0x1: 589 if (rn == 0xf) { 590 return new Uxth(machInst, rd, rotation, rm); 591 } else { 592 return new Uxtah(machInst, rd, rn, rm, rotation); 593 } 594 case 0x2: 595 if (rn == 0xf) { 596 return new Sxtb16(machInst, rd, rotation, rm); 597 } else { 598 return new Sxtab16(machInst, rd, rn, rm, rotation); 599 } 600 case 0x3: 601 if (rn == 0xf) { 602 return new Uxtb16(machInst, rd, rotation, rm); 603 } else { 604 return new Uxtab16(machInst, rd, rn, rm, rotation); 605 } 606 case 0x4: 607 if (rn == 0xf) { 608 return new Sxtb(machInst, rd, rotation, rm); 609 } else { 610 return new Sxtab(machInst, rd, rn, rm, rotation); 611 } 612 case 0x5: 613 if (rn == 0xf) { 614 return new Uxtb(machInst, rd, rotation, rm); 615 } else { 616 return new Uxtab(machInst, rd, rn, rm, rotation); 617 } 618 default: 619 return new Unknown(machInst); 620 } 621 } 622 } else { 623 if (bits(op2, 3) == 0) { 624 const IntRegIndex rd = 625 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 626 const IntRegIndex rm = 627 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 628 if (bits(op2, 2) == 0x0) { 629 const uint32_t op1 = bits(machInst, 22, 20); 630 const uint32_t op2 = bits(machInst, 5, 4); 631 switch (op2) { 632 case 0x0: 633 switch (op1) { 634 case 0x1: 635 return new Sadd16RegCc(machInst, rd, 636 rn, rm, 0, LSL); 637 case 0x2: 638 return new SasxRegCc(machInst, rd, 639 rn, rm, 0, LSL); 640 case 0x6: 641 return new SsaxRegCc(machInst, rd, 642 rn, rm, 0, LSL); 643 case 0x5: 644 return new Ssub16RegCc(machInst, rd, 645 rn, rm, 0, LSL); 646 case 0x0: 647 return new Sadd8RegCc(machInst, rd, 648 rn, rm, 0, LSL); 649 case 0x4: 650 return new Ssub8RegCc(machInst, rd, 651 rn, rm, 0, LSL); 652 } 653 break; 654 case 0x1: 655 switch (op1) { 656 case 0x1: 657 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 658 case 0x2: 659 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 660 case 0x6: 661 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 662 case 0x5: 663 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 664 case 0x0: 665 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 666 case 0x4: 667 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 668 } 669 break; 670 case 0x2: 671 switch (op1) { 672 case 0x1: 673 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 674 case 0x2: 675 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 676 case 0x6: 677 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 678 case 0x5: 679 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 680 case 0x0: 681 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 682 case 0x4: 683 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 684 } 685 break; 686 } 687 } else { 688 const uint32_t op1 = bits(machInst, 22, 20); 689 const uint32_t op2 = bits(machInst, 5, 4); 690 switch (op2) { 691 case 0x0: 692 switch (op1) { 693 case 0x1: 694 return new Uadd16RegCc(machInst, rd, 695 rn, rm, 0, LSL); 696 case 0x2: 697 return new UasxRegCc(machInst, rd, 698 rn, rm, 0, LSL); 699 case 0x6: 700 return new UsaxRegCc(machInst, rd, 701 rn, rm, 0, LSL); 702 case 0x5: 703 return new Usub16RegCc(machInst, rd, 704 rn, rm, 0, LSL); 705 case 0x0: 706 return new Uadd8RegCc(machInst, rd, 707 rn, rm, 0, LSL); 708 case 0x4: 709 return new Usub8RegCc(machInst, rd, 710 rn, rm, 0, LSL); 711 } 712 break; 713 case 0x1: 714 switch (op1) { 715 case 0x1: 716 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 717 case 0x2: 718 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 719 case 0x6: 720 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 721 case 0x5: 722 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 723 case 0x0: 724 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 725 case 0x4: 726 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 727 } 728 break; 729 case 0x2: 730 switch (op1) { 731 case 0x1: 732 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 733 case 0x2: 734 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 735 case 0x6: 736 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 737 case 0x5: 738 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 739 case 0x0: 740 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 741 case 0x4: 742 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 743 } 744 break; 745 } 746 } 747 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) { 748 const uint32_t op1 = bits(machInst, 21, 20); 749 const uint32_t op2 = bits(machInst, 5, 4);
|
| 750 const IntRegIndex rd = 751 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 752 const IntRegIndex rm = 753 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
|
748 switch (op1) { 749 case 0x0:
| 754 switch (op1) { 755 case 0x0:
|
750 { 751 IntRegIndex rd = 752 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 753 IntRegIndex rm = 754 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 755 switch (op2) { 756 case 0x0: 757 return new QaddRegCc(machInst, rd, 758 rm, rn, 0, LSL); 759 case 0x1: 760 return new QdaddRegCc(machInst, rd, 761 rm, rn, 0, LSL); 762 case 0x2: 763 return new QsubRegCc(machInst, rd, 764 rm, rn, 0, LSL); 765 case 0x3: 766 return new QdsubRegCc(machInst, rd, 767 rm, rn, 0, LSL); 768 }
| 756 switch (op2) { 757 case 0x0: 758 return new QaddRegCc(machInst, rd, 759 rm, rn, 0, LSL); 760 case 0x1: 761 return new QdaddRegCc(machInst, rd, 762 rm, rn, 0, LSL); 763 case 0x2: 764 return new QsubRegCc(machInst, rd, 765 rm, rn, 0, LSL); 766 case 0x3: 767 return new QdsubRegCc(machInst, rd, 768 rm, rn, 0, LSL);
|
769 } 770 break; 771 case 0x1:
| 769 } 770 break; 771 case 0x1:
|
772 { 773 IntRegIndex rd = 774 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 775 IntRegIndex rm = rn; 776 switch (op2) { 777 case 0x0: 778 return new Rev(machInst, rd, rm); 779 case 0x1: 780 return new Rev16(machInst, rd, rm); 781 case 0x2: 782 return new WarnUnimplemented("rbit", machInst); 783 case 0x3: 784 return new Revsh(machInst, rd, rm); 785 }
| 772 switch (op2) { 773 case 0x0: 774 return new Rev(machInst, rd, rn); 775 case 0x1: 776 return new Rev16(machInst, rd, rn); 777 case 0x2: 778 return new WarnUnimplemented("rbit", machInst); 779 case 0x3: 780 return new Revsh(machInst, rd, rn);
|
786 } 787 break; 788 case 0x2: 789 if (op2 == 0) {
| 781 } 782 break; 783 case 0x2: 784 if (op2 == 0) {
|
790 return new WarnUnimplemented("sel", machInst);
| 785 return new Sel(machInst, rd, rn, rm);
|
791 } 792 break; 793 case 0x3: 794 if (op2 == 0) { 795 return new WarnUnimplemented("clz", machInst); 796 } 797 } 798 } 799 return new Unknown(machInst); 800 } 801 } 802 ''' 803}}; 804 805def format Thumb16ShiftAddSubMoveCmp() {{ 806 decode_block = ''' 807 { 808 const uint32_t imm5 = bits(machInst, 10, 6); 809 const uint32_t imm3 = bits(machInst, 8, 6); 810 const uint32_t imm8 = bits(machInst, 7, 0); 811 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 812 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 813 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 814 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); 815 switch (bits(machInst, 13, 11)) { 816 case 0x0: // lsl 817 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); 818 case 0x1: // lsr 819 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); 820 case 0x2: // asr 821 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); 822 case 0x3: 823 switch (bits(machInst, 10, 9)) { 824 case 0x0: 825 return new AddRegCc(machInst, rd, rn, rm, 0, LSL); 826 case 0x1: 827 return new SubRegCc(machInst, rd, rn, rm, 0, LSL); 828 case 0x2: 829 return new AddImmCc(machInst, rd, rn, imm3, true); 830 case 0x3: 831 return new SubImmCc(machInst, rd, rn, imm3, true); 832 } 833 case 0x4: 834 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); 835 case 0x5: 836 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); 837 case 0x6: 838 return new AddImmCc(machInst, rd8, rd8, imm8, true); 839 case 0x7: 840 return new SubImmCc(machInst, rd8, rd8, imm8, true); 841 } 842 } 843 ''' 844}}; 845 846def format Thumb16DataProcessing() {{ 847 decode_block = ''' 848 { 849 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 850 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 851 switch (bits(machInst, 9, 6)) { 852 case 0x0: 853 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); 854 case 0x1: 855 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); 856 case 0x2: //lsl 857 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); 858 case 0x3: //lsr 859 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); 860 case 0x4: //asr 861 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); 862 case 0x5: 863 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); 864 case 0x6: 865 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); 866 case 0x7: // ror 867 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); 868 case 0x8: 869 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 870 case 0x9: 871 return new RsbImmCc(machInst, rdn, rm, 0, true); 872 case 0xa: 873 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 874 case 0xb: 875 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 876 case 0xc: 877 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); 878 case 0xd: 879 return new MulCc(machInst, rdn, rm, rdn); 880 case 0xe: 881 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); 882 case 0xf: 883 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 884 } 885 } 886 ''' 887}}; 888 889def format Thumb16SpecDataAndBx() {{ 890 decode_block = ''' 891 { 892 const IntRegIndex rdn = 893 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) | 894 (bits(machInst, 7) << 3)); 895 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3); 896 switch (bits(machInst, 9, 8)) { 897 case 0x0: 898 return new AddReg(machInst, rdn, rdn, rm, 0, LSL); 899 case 0x1: 900 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 901 case 0x2: 902 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 903 case 0x3: 904 if (bits(machInst, 7) == 0) { 905 return new BxReg(machInst, 906 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 907 COND_UC); 908 } else { 909 return new BlxReg(machInst, 910 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 911 COND_UC); 912 } 913 } 914 } 915 ''' 916}}; 917 918def format Thumb16Adr() {{ 919 decode_block = ''' 920 { 921 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 922 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 923 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false); 924 } 925 ''' 926}}; 927 928def format Thumb16AddSp() {{ 929 decode_block = ''' 930 { 931 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 932 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 933 return new AddImm(machInst, rd, INTREG_SP, imm8, true); 934 } 935 ''' 936}}; 937 938def format Thumb16Misc() {{ 939 decode_block = ''' 940 { 941 switch (bits(machInst, 11, 8)) { 942 case 0x0: 943 if (bits(machInst, 7)) { 944 return new SubImm(machInst, INTREG_SP, INTREG_SP, 945 bits(machInst, 6, 0) << 2, true); 946 } else { 947 return new AddImm(machInst, INTREG_SP, INTREG_SP, 948 bits(machInst, 6, 0) << 2, true); 949 } 950 case 0x1: 951 return new Cbz(machInst, 952 (bits(machInst, 9) << 6) | 953 (bits(machInst, 7, 3) << 1), 954 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 955 case 0x2: 956 { 957 const IntRegIndex rd = 958 (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 959 const IntRegIndex rm = 960 (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 961 switch (bits(machInst, 7, 6)) { 962 case 0x0: 963 return new Sxth(machInst, rd, 0, rm); 964 case 0x1: 965 return new Sxtb(machInst, rd, 0, rm); 966 case 0x2: 967 return new Uxth(machInst, rd, 0, rm); 968 case 0x3: 969 return new Uxtb(machInst, rd, 0, rm); 970 } 971 } 972 case 0x3: 973 return new Cbz(machInst, 974 (bits(machInst, 9) << 6) | 975 (bits(machInst, 7, 3) << 1), 976 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 977 case 0x4: 978 case 0x5: 979 { 980 const uint32_t m = bits(machInst, 8); 981 const uint32_t regList = bits(machInst, 7, 0) | (m << 14); 982 return new LdmStm(machInst, INTREG_SP, false, false, false, 983 true, false, regList); 984 } 985 case 0x6: 986 { 987 const uint32_t opBits = bits(machInst, 7, 5); 988 if (opBits == 2) { 989 return new WarnUnimplemented("setend", machInst); 990 } else if (opBits == 3) { 991 return new WarnUnimplemented("cps", machInst); 992 } 993 } 994 case 0x9: 995 return new Cbnz(machInst, 996 (bits(machInst, 9) << 6) | 997 (bits(machInst, 7, 3) << 1), 998 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 999 case 0xa: 1000 { 1001 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 1002 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 1003 switch (bits(machInst, 7, 6)) { 1004 case 0x0: 1005 return new Rev(machInst, rd, rm); 1006 case 0x1: 1007 return new Rev16(machInst, rd, rm); 1008 case 0x3: 1009 return new Revsh(machInst, rd, rm); 1010 default: 1011 break; 1012 } 1013 } 1014 break; 1015 case 0xb: 1016 return new Cbnz(machInst, 1017 (bits(machInst, 9) << 6) | 1018 (bits(machInst, 7, 3) << 1), 1019 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 1020 case 0xc: 1021 case 0xd: 1022 { 1023 const uint32_t p = bits(machInst, 8); 1024 const uint32_t regList = bits(machInst, 7, 0) | (p << 15); 1025 return new LdmStm(machInst, INTREG_SP, true, true, false, 1026 true, true, regList); 1027 } 1028 case 0xe: 1029 return new WarnUnimplemented("bkpt", machInst); 1030 case 0xf: 1031 if (bits(machInst, 3, 0) != 0) 1032 return new WarnUnimplemented("it", machInst); 1033 switch (bits(machInst, 7, 4)) { 1034 case 0x0: 1035 return new WarnUnimplemented("nop", machInst); 1036 case 0x1: 1037 return new WarnUnimplemented("yield", machInst); 1038 case 0x2: 1039 return new WarnUnimplemented("wfe", machInst); 1040 case 0x3: 1041 return new WarnUnimplemented("wfi", machInst); 1042 case 0x4: 1043 return new WarnUnimplemented("sev", machInst); 1044 default: 1045 return new WarnUnimplemented("unallocated_hint", machInst); 1046 } 1047 default: 1048 break; 1049 } 1050 return new Unknown(machInst); 1051 } 1052 ''' 1053}}; 1054 1055def format Thumb32DataProcModImm() {{ 1056 1057 def decInst(mnem, dest="rd", op1="rn"): 1058 return ''' 1059 if (s) { 1060 return new %(mnem)sImmCc(machInst, %(dest)s, 1061 %(op1)s, imm, rotC); 1062 } else { 1063 return new %(mnem)sImm(machInst, %(dest)s, 1064 %(op1)s, imm, rotC); 1065 } 1066 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1067 1068 decode_block = ''' 1069 { 1070 const uint32_t op = bits(machInst, 24, 21); 1071 const bool s = (bits(machInst, 20) == 1); 1072 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1073 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1074 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 | 1075 bits(machInst, 14, 12); 1076 const bool rotC = ctrlImm > 3; 1077 const uint32_t dataImm = bits(machInst, 7, 0); 1078 const uint32_t imm = modified_imm(ctrlImm, dataImm); 1079 switch (op) { 1080 case 0x0: 1081 if (rd == INTREG_PC) { 1082 %(tst)s 1083 } else { 1084 %(and)s 1085 } 1086 case 0x1: 1087 %(bic)s 1088 case 0x2: 1089 if (rn == INTREG_PC) { 1090 %(mov)s 1091 } else { 1092 %(orr)s 1093 } 1094 case 0x3: 1095 if (rn == INTREG_PC) { 1096 %(mvn)s 1097 } else { 1098 %(orn)s 1099 } 1100 case 0x4: 1101 if (rd == INTREG_PC) { 1102 %(teq)s 1103 } else { 1104 %(eor)s 1105 } 1106 case 0x8: 1107 if (rd == INTREG_PC) { 1108 %(cmn)s 1109 } else { 1110 %(add)s 1111 } 1112 case 0xa: 1113 %(adc)s 1114 case 0xb: 1115 %(sbc)s 1116 case 0xd: 1117 if (rd == INTREG_PC) { 1118 %(cmp)s 1119 } else { 1120 %(sub)s 1121 } 1122 case 0xe: 1123 %(rsb)s 1124 default: 1125 return new Unknown(machInst); 1126 } 1127 } 1128 ''' % { 1129 "tst" : decInst("Tst", "INTREG_ZERO"), 1130 "and" : decInst("And"), 1131 "bic" : decInst("Bic"), 1132 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1133 "orr" : decInst("Orr"), 1134 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1135 "orn" : decInst("Orn"), 1136 "teq" : decInst("Teq", dest="INTREG_ZERO"), 1137 "eor" : decInst("Eor"), 1138 "cmn" : decInst("Cmn", dest="INTREG_ZERO"), 1139 "add" : decInst("Add"), 1140 "adc" : decInst("Adc"), 1141 "sbc" : decInst("Sbc"), 1142 "cmp" : decInst("Cmp", dest="INTREG_ZERO"), 1143 "sub" : decInst("Sub"), 1144 "rsb" : decInst("Rsb") 1145 } 1146}}; 1147 1148def format Thumb32DataProcPlainBin() {{ 1149 decode_block = ''' 1150 { 1151 const uint32_t op = bits(machInst, 24, 20); 1152 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1153 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1154 switch (op) { 1155 case 0x0: 1156 { 1157 const uint32_t imm = bits(machInst, 7, 0) | 1158 (bits(machInst, 14, 12) << 8) | 1159 (bits(machInst, 26) << 11); 1160 if (rn == 0xf) { 1161 return new AdrImm(machInst, rd, (IntRegIndex)1, 1162 imm, false); 1163 } else { 1164 return new AddImm(machInst, rd, rn, imm, true); 1165 } 1166 } 1167 case 0x4: 1168 { 1169 const uint32_t imm = bits(machInst, 7, 0) | 1170 (bits(machInst, 14, 12) << 8) | 1171 (bits(machInst, 26) << 11) | 1172 (bits(machInst, 19, 16) << 12); 1173 return new MovImm(machInst, rd, INTREG_ZERO, imm, true); 1174 } 1175 case 0xa: 1176 { 1177 const uint32_t imm = bits(machInst, 7, 0) | 1178 (bits(machInst, 14, 12) << 8) | 1179 (bits(machInst, 26) << 11); 1180 if (rn == 0xf) { 1181 return new AdrImm(machInst, rd, (IntRegIndex)0, 1182 imm, false); 1183 } else { 1184 return new SubImm(machInst, rd, rn, imm, true); 1185 } 1186 } 1187 case 0xc: 1188 { 1189 const uint32_t imm = bits(machInst, 7, 0) | 1190 (bits(machInst, 14, 12) << 8) | 1191 (bits(machInst, 26) << 11) | 1192 (bits(machInst, 19, 16) << 12); 1193 return new MovtImm(machInst, rd, rd, imm, true); 1194 } 1195 case 0x12: 1196 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1197 const uint32_t satImm = bits(machInst, 4, 0); 1198 return new Ssat16(machInst, rd, satImm + 1, rn); 1199 } 1200 // Fall through on purpose... 1201 case 0x10: 1202 { 1203 const uint32_t satImm = bits(machInst, 4, 0); 1204 const uint32_t imm = bits(machInst, 7, 6) | 1205 (bits(machInst, 14, 12) << 2); 1206 const ArmShiftType type = 1207 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1208 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 1209 } 1210 case 0x14: 1211 return new WarnUnimplemented("sbfx", machInst); 1212 case 0x16: 1213 if (rn == 0xf) { 1214 return new WarnUnimplemented("bfc", machInst); 1215 } else { 1216 return new WarnUnimplemented("bfi", machInst); 1217 } 1218 case 0x1a: 1219 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1220 const uint32_t satImm = bits(machInst, 4, 0); 1221 return new Usat16(machInst, rd, satImm, rn); 1222 } 1223 // Fall through on purpose... 1224 case 0x18: 1225 { 1226 const uint32_t satImm = bits(machInst, 4, 0); 1227 const uint32_t imm = bits(machInst, 7, 6) | 1228 (bits(machInst, 14, 12) << 2); 1229 const ArmShiftType type = 1230 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1231 return new Usat(machInst, rd, satImm, rn, imm, type); 1232 } 1233 case 0x1c: 1234 return new WarnUnimplemented("ubfx", machInst); 1235 default: 1236 return new Unknown(machInst); 1237 } 1238 } 1239 ''' 1240}}; 1241 1242def format Thumb32DataProcShiftReg() {{ 1243 1244 def decInst(mnem, dest="rd", op1="rn"): 1245 return ''' 1246 if (s) { 1247 return new %(mnem)sRegCc(machInst, %(dest)s, 1248 %(op1)s, rm, amt, type); 1249 } else { 1250 return new %(mnem)sReg(machInst, %(dest)s, 1251 %(op1)s, rm, amt, type); 1252 } 1253 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1254 1255 decode_block = ''' 1256 { 1257 const uint32_t op = bits(machInst, 24, 21); 1258 const bool s = (bits(machInst, 20) == 1); 1259 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1260 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1261 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 1262 const uint32_t amt = (bits(machInst, 14, 12) << 2) | 1263 bits(machInst, 7, 6); 1264 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4); 1265 switch (op) { 1266 case 0x0: 1267 if (rd == INTREG_PC) { 1268 %(tst)s 1269 } else { 1270 %(and)s 1271 } 1272 case 0x1: 1273 %(bic)s 1274 case 0x2: 1275 if (rn == INTREG_PC) { 1276 %(mov)s 1277 } else { 1278 %(orr)s 1279 } 1280 case 0x3: 1281 if (rn == INTREG_PC) { 1282 %(mvn)s 1283 } else { 1284 %(orn)s 1285 } 1286 case 0x4: 1287 if (rd == INTREG_PC) { 1288 %(teq)s 1289 } else { 1290 %(eor)s 1291 } 1292 case 0x6: 1293 if (type) { 1294 return new PkhtbReg(machInst, rd, rn, rm, amt, type); 1295 } else { 1296 return new PkhbtReg(machInst, rd, rn, rm, amt, type); 1297 } 1298 case 0x8: 1299 if (rd == INTREG_PC) { 1300 %(cmn)s 1301 } else { 1302 %(add)s 1303 } 1304 case 0xa: 1305 %(adc)s 1306 case 0xb: 1307 %(sbc)s 1308 case 0xd: 1309 if (rd == INTREG_PC) { 1310 %(cmp)s 1311 } else { 1312 %(sub)s 1313 } 1314 case 0xe: 1315 %(rsb)s 1316 default: 1317 return new Unknown(machInst); 1318 } 1319 } 1320 ''' % { 1321 "tst" : decInst("Tst", "INTREG_ZERO"), 1322 "and" : decInst("And"), 1323 "bic" : decInst("Bic"), 1324 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1325 "orr" : decInst("Orr"), 1326 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1327 "orn" : decInst("Orn"), 1328 "teq" : decInst("Teq", "INTREG_ZERO"), 1329 "eor" : decInst("Eor"), 1330 "cmn" : decInst("Cmn", "INTREG_ZERO"), 1331 "add" : decInst("Add"), 1332 "adc" : decInst("Adc"), 1333 "sbc" : decInst("Sbc"), 1334 "cmp" : decInst("Cmp", "INTREG_ZERO"), 1335 "sub" : decInst("Sub"), 1336 "rsb" : decInst("Rsb") 1337 } 1338}};
| 786 } 787 break; 788 case 0x3: 789 if (op2 == 0) { 790 return new WarnUnimplemented("clz", machInst); 791 } 792 } 793 } 794 return new Unknown(machInst); 795 } 796 } 797 ''' 798}}; 799 800def format Thumb16ShiftAddSubMoveCmp() {{ 801 decode_block = ''' 802 { 803 const uint32_t imm5 = bits(machInst, 10, 6); 804 const uint32_t imm3 = bits(machInst, 8, 6); 805 const uint32_t imm8 = bits(machInst, 7, 0); 806 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 807 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 808 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 809 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); 810 switch (bits(machInst, 13, 11)) { 811 case 0x0: // lsl 812 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); 813 case 0x1: // lsr 814 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); 815 case 0x2: // asr 816 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); 817 case 0x3: 818 switch (bits(machInst, 10, 9)) { 819 case 0x0: 820 return new AddRegCc(machInst, rd, rn, rm, 0, LSL); 821 case 0x1: 822 return new SubRegCc(machInst, rd, rn, rm, 0, LSL); 823 case 0x2: 824 return new AddImmCc(machInst, rd, rn, imm3, true); 825 case 0x3: 826 return new SubImmCc(machInst, rd, rn, imm3, true); 827 } 828 case 0x4: 829 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); 830 case 0x5: 831 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); 832 case 0x6: 833 return new AddImmCc(machInst, rd8, rd8, imm8, true); 834 case 0x7: 835 return new SubImmCc(machInst, rd8, rd8, imm8, true); 836 } 837 } 838 ''' 839}}; 840 841def format Thumb16DataProcessing() {{ 842 decode_block = ''' 843 { 844 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 845 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 846 switch (bits(machInst, 9, 6)) { 847 case 0x0: 848 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); 849 case 0x1: 850 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); 851 case 0x2: //lsl 852 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); 853 case 0x3: //lsr 854 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); 855 case 0x4: //asr 856 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); 857 case 0x5: 858 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); 859 case 0x6: 860 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); 861 case 0x7: // ror 862 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); 863 case 0x8: 864 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 865 case 0x9: 866 return new RsbImmCc(machInst, rdn, rm, 0, true); 867 case 0xa: 868 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 869 case 0xb: 870 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 871 case 0xc: 872 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); 873 case 0xd: 874 return new MulCc(machInst, rdn, rm, rdn); 875 case 0xe: 876 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); 877 case 0xf: 878 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 879 } 880 } 881 ''' 882}}; 883 884def format Thumb16SpecDataAndBx() {{ 885 decode_block = ''' 886 { 887 const IntRegIndex rdn = 888 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) | 889 (bits(machInst, 7) << 3)); 890 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3); 891 switch (bits(machInst, 9, 8)) { 892 case 0x0: 893 return new AddReg(machInst, rdn, rdn, rm, 0, LSL); 894 case 0x1: 895 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 896 case 0x2: 897 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 898 case 0x3: 899 if (bits(machInst, 7) == 0) { 900 return new BxReg(machInst, 901 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 902 COND_UC); 903 } else { 904 return new BlxReg(machInst, 905 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 906 COND_UC); 907 } 908 } 909 } 910 ''' 911}}; 912 913def format Thumb16Adr() {{ 914 decode_block = ''' 915 { 916 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 917 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 918 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false); 919 } 920 ''' 921}}; 922 923def format Thumb16AddSp() {{ 924 decode_block = ''' 925 { 926 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 927 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 928 return new AddImm(machInst, rd, INTREG_SP, imm8, true); 929 } 930 ''' 931}}; 932 933def format Thumb16Misc() {{ 934 decode_block = ''' 935 { 936 switch (bits(machInst, 11, 8)) { 937 case 0x0: 938 if (bits(machInst, 7)) { 939 return new SubImm(machInst, INTREG_SP, INTREG_SP, 940 bits(machInst, 6, 0) << 2, true); 941 } else { 942 return new AddImm(machInst, INTREG_SP, INTREG_SP, 943 bits(machInst, 6, 0) << 2, true); 944 } 945 case 0x1: 946 return new Cbz(machInst, 947 (bits(machInst, 9) << 6) | 948 (bits(machInst, 7, 3) << 1), 949 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 950 case 0x2: 951 { 952 const IntRegIndex rd = 953 (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 954 const IntRegIndex rm = 955 (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 956 switch (bits(machInst, 7, 6)) { 957 case 0x0: 958 return new Sxth(machInst, rd, 0, rm); 959 case 0x1: 960 return new Sxtb(machInst, rd, 0, rm); 961 case 0x2: 962 return new Uxth(machInst, rd, 0, rm); 963 case 0x3: 964 return new Uxtb(machInst, rd, 0, rm); 965 } 966 } 967 case 0x3: 968 return new Cbz(machInst, 969 (bits(machInst, 9) << 6) | 970 (bits(machInst, 7, 3) << 1), 971 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 972 case 0x4: 973 case 0x5: 974 { 975 const uint32_t m = bits(machInst, 8); 976 const uint32_t regList = bits(machInst, 7, 0) | (m << 14); 977 return new LdmStm(machInst, INTREG_SP, false, false, false, 978 true, false, regList); 979 } 980 case 0x6: 981 { 982 const uint32_t opBits = bits(machInst, 7, 5); 983 if (opBits == 2) { 984 return new WarnUnimplemented("setend", machInst); 985 } else if (opBits == 3) { 986 return new WarnUnimplemented("cps", machInst); 987 } 988 } 989 case 0x9: 990 return new Cbnz(machInst, 991 (bits(machInst, 9) << 6) | 992 (bits(machInst, 7, 3) << 1), 993 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 994 case 0xa: 995 { 996 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 997 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 998 switch (bits(machInst, 7, 6)) { 999 case 0x0: 1000 return new Rev(machInst, rd, rm); 1001 case 0x1: 1002 return new Rev16(machInst, rd, rm); 1003 case 0x3: 1004 return new Revsh(machInst, rd, rm); 1005 default: 1006 break; 1007 } 1008 } 1009 break; 1010 case 0xb: 1011 return new Cbnz(machInst, 1012 (bits(machInst, 9) << 6) | 1013 (bits(machInst, 7, 3) << 1), 1014 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 1015 case 0xc: 1016 case 0xd: 1017 { 1018 const uint32_t p = bits(machInst, 8); 1019 const uint32_t regList = bits(machInst, 7, 0) | (p << 15); 1020 return new LdmStm(machInst, INTREG_SP, true, true, false, 1021 true, true, regList); 1022 } 1023 case 0xe: 1024 return new WarnUnimplemented("bkpt", machInst); 1025 case 0xf: 1026 if (bits(machInst, 3, 0) != 0) 1027 return new WarnUnimplemented("it", machInst); 1028 switch (bits(machInst, 7, 4)) { 1029 case 0x0: 1030 return new WarnUnimplemented("nop", machInst); 1031 case 0x1: 1032 return new WarnUnimplemented("yield", machInst); 1033 case 0x2: 1034 return new WarnUnimplemented("wfe", machInst); 1035 case 0x3: 1036 return new WarnUnimplemented("wfi", machInst); 1037 case 0x4: 1038 return new WarnUnimplemented("sev", machInst); 1039 default: 1040 return new WarnUnimplemented("unallocated_hint", machInst); 1041 } 1042 default: 1043 break; 1044 } 1045 return new Unknown(machInst); 1046 } 1047 ''' 1048}}; 1049 1050def format Thumb32DataProcModImm() {{ 1051 1052 def decInst(mnem, dest="rd", op1="rn"): 1053 return ''' 1054 if (s) { 1055 return new %(mnem)sImmCc(machInst, %(dest)s, 1056 %(op1)s, imm, rotC); 1057 } else { 1058 return new %(mnem)sImm(machInst, %(dest)s, 1059 %(op1)s, imm, rotC); 1060 } 1061 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1062 1063 decode_block = ''' 1064 { 1065 const uint32_t op = bits(machInst, 24, 21); 1066 const bool s = (bits(machInst, 20) == 1); 1067 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1068 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1069 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 | 1070 bits(machInst, 14, 12); 1071 const bool rotC = ctrlImm > 3; 1072 const uint32_t dataImm = bits(machInst, 7, 0); 1073 const uint32_t imm = modified_imm(ctrlImm, dataImm); 1074 switch (op) { 1075 case 0x0: 1076 if (rd == INTREG_PC) { 1077 %(tst)s 1078 } else { 1079 %(and)s 1080 } 1081 case 0x1: 1082 %(bic)s 1083 case 0x2: 1084 if (rn == INTREG_PC) { 1085 %(mov)s 1086 } else { 1087 %(orr)s 1088 } 1089 case 0x3: 1090 if (rn == INTREG_PC) { 1091 %(mvn)s 1092 } else { 1093 %(orn)s 1094 } 1095 case 0x4: 1096 if (rd == INTREG_PC) { 1097 %(teq)s 1098 } else { 1099 %(eor)s 1100 } 1101 case 0x8: 1102 if (rd == INTREG_PC) { 1103 %(cmn)s 1104 } else { 1105 %(add)s 1106 } 1107 case 0xa: 1108 %(adc)s 1109 case 0xb: 1110 %(sbc)s 1111 case 0xd: 1112 if (rd == INTREG_PC) { 1113 %(cmp)s 1114 } else { 1115 %(sub)s 1116 } 1117 case 0xe: 1118 %(rsb)s 1119 default: 1120 return new Unknown(machInst); 1121 } 1122 } 1123 ''' % { 1124 "tst" : decInst("Tst", "INTREG_ZERO"), 1125 "and" : decInst("And"), 1126 "bic" : decInst("Bic"), 1127 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1128 "orr" : decInst("Orr"), 1129 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1130 "orn" : decInst("Orn"), 1131 "teq" : decInst("Teq", dest="INTREG_ZERO"), 1132 "eor" : decInst("Eor"), 1133 "cmn" : decInst("Cmn", dest="INTREG_ZERO"), 1134 "add" : decInst("Add"), 1135 "adc" : decInst("Adc"), 1136 "sbc" : decInst("Sbc"), 1137 "cmp" : decInst("Cmp", dest="INTREG_ZERO"), 1138 "sub" : decInst("Sub"), 1139 "rsb" : decInst("Rsb") 1140 } 1141}}; 1142 1143def format Thumb32DataProcPlainBin() {{ 1144 decode_block = ''' 1145 { 1146 const uint32_t op = bits(machInst, 24, 20); 1147 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1148 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1149 switch (op) { 1150 case 0x0: 1151 { 1152 const uint32_t imm = bits(machInst, 7, 0) | 1153 (bits(machInst, 14, 12) << 8) | 1154 (bits(machInst, 26) << 11); 1155 if (rn == 0xf) { 1156 return new AdrImm(machInst, rd, (IntRegIndex)1, 1157 imm, false); 1158 } else { 1159 return new AddImm(machInst, rd, rn, imm, true); 1160 } 1161 } 1162 case 0x4: 1163 { 1164 const uint32_t imm = bits(machInst, 7, 0) | 1165 (bits(machInst, 14, 12) << 8) | 1166 (bits(machInst, 26) << 11) | 1167 (bits(machInst, 19, 16) << 12); 1168 return new MovImm(machInst, rd, INTREG_ZERO, imm, true); 1169 } 1170 case 0xa: 1171 { 1172 const uint32_t imm = bits(machInst, 7, 0) | 1173 (bits(machInst, 14, 12) << 8) | 1174 (bits(machInst, 26) << 11); 1175 if (rn == 0xf) { 1176 return new AdrImm(machInst, rd, (IntRegIndex)0, 1177 imm, false); 1178 } else { 1179 return new SubImm(machInst, rd, rn, imm, true); 1180 } 1181 } 1182 case 0xc: 1183 { 1184 const uint32_t imm = bits(machInst, 7, 0) | 1185 (bits(machInst, 14, 12) << 8) | 1186 (bits(machInst, 26) << 11) | 1187 (bits(machInst, 19, 16) << 12); 1188 return new MovtImm(machInst, rd, rd, imm, true); 1189 } 1190 case 0x12: 1191 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1192 const uint32_t satImm = bits(machInst, 4, 0); 1193 return new Ssat16(machInst, rd, satImm + 1, rn); 1194 } 1195 // Fall through on purpose... 1196 case 0x10: 1197 { 1198 const uint32_t satImm = bits(machInst, 4, 0); 1199 const uint32_t imm = bits(machInst, 7, 6) | 1200 (bits(machInst, 14, 12) << 2); 1201 const ArmShiftType type = 1202 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1203 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 1204 } 1205 case 0x14: 1206 return new WarnUnimplemented("sbfx", machInst); 1207 case 0x16: 1208 if (rn == 0xf) { 1209 return new WarnUnimplemented("bfc", machInst); 1210 } else { 1211 return new WarnUnimplemented("bfi", machInst); 1212 } 1213 case 0x1a: 1214 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1215 const uint32_t satImm = bits(machInst, 4, 0); 1216 return new Usat16(machInst, rd, satImm, rn); 1217 } 1218 // Fall through on purpose... 1219 case 0x18: 1220 { 1221 const uint32_t satImm = bits(machInst, 4, 0); 1222 const uint32_t imm = bits(machInst, 7, 6) | 1223 (bits(machInst, 14, 12) << 2); 1224 const ArmShiftType type = 1225 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1226 return new Usat(machInst, rd, satImm, rn, imm, type); 1227 } 1228 case 0x1c: 1229 return new WarnUnimplemented("ubfx", machInst); 1230 default: 1231 return new Unknown(machInst); 1232 } 1233 } 1234 ''' 1235}}; 1236 1237def format Thumb32DataProcShiftReg() {{ 1238 1239 def decInst(mnem, dest="rd", op1="rn"): 1240 return ''' 1241 if (s) { 1242 return new %(mnem)sRegCc(machInst, %(dest)s, 1243 %(op1)s, rm, amt, type); 1244 } else { 1245 return new %(mnem)sReg(machInst, %(dest)s, 1246 %(op1)s, rm, amt, type); 1247 } 1248 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1249 1250 decode_block = ''' 1251 { 1252 const uint32_t op = bits(machInst, 24, 21); 1253 const bool s = (bits(machInst, 20) == 1); 1254 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1255 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1256 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 1257 const uint32_t amt = (bits(machInst, 14, 12) << 2) | 1258 bits(machInst, 7, 6); 1259 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4); 1260 switch (op) { 1261 case 0x0: 1262 if (rd == INTREG_PC) { 1263 %(tst)s 1264 } else { 1265 %(and)s 1266 } 1267 case 0x1: 1268 %(bic)s 1269 case 0x2: 1270 if (rn == INTREG_PC) { 1271 %(mov)s 1272 } else { 1273 %(orr)s 1274 } 1275 case 0x3: 1276 if (rn == INTREG_PC) { 1277 %(mvn)s 1278 } else { 1279 %(orn)s 1280 } 1281 case 0x4: 1282 if (rd == INTREG_PC) { 1283 %(teq)s 1284 } else { 1285 %(eor)s 1286 } 1287 case 0x6: 1288 if (type) { 1289 return new PkhtbReg(machInst, rd, rn, rm, amt, type); 1290 } else { 1291 return new PkhbtReg(machInst, rd, rn, rm, amt, type); 1292 } 1293 case 0x8: 1294 if (rd == INTREG_PC) { 1295 %(cmn)s 1296 } else { 1297 %(add)s 1298 } 1299 case 0xa: 1300 %(adc)s 1301 case 0xb: 1302 %(sbc)s 1303 case 0xd: 1304 if (rd == INTREG_PC) { 1305 %(cmp)s 1306 } else { 1307 %(sub)s 1308 } 1309 case 0xe: 1310 %(rsb)s 1311 default: 1312 return new Unknown(machInst); 1313 } 1314 } 1315 ''' % { 1316 "tst" : decInst("Tst", "INTREG_ZERO"), 1317 "and" : decInst("And"), 1318 "bic" : decInst("Bic"), 1319 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1320 "orr" : decInst("Orr"), 1321 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1322 "orn" : decInst("Orn"), 1323 "teq" : decInst("Teq", "INTREG_ZERO"), 1324 "eor" : decInst("Eor"), 1325 "cmn" : decInst("Cmn", "INTREG_ZERO"), 1326 "add" : decInst("Add"), 1327 "adc" : decInst("Adc"), 1328 "sbc" : decInst("Sbc"), 1329 "cmp" : decInst("Cmp", "INTREG_ZERO"), 1330 "sub" : decInst("Sub"), 1331 "rsb" : decInst("Rsb") 1332 } 1333}};
|