3c3
< // Copyright (c) 2010-2012 ARM Limited
---
> // Copyright (c) 2010-2013 ARM Limited
38a39
> // Giacomo Gabrielli
39a41,44
> def format ArmERet() {{
> decode_block = "return new Eret(machInst);"
> }};
>
41c46
< decode_block = "return new Svc(machInst);"
---
> decode_block = "return new Svc(machInst, bits(machInst, 23, 0));"
43a49,63
> def format ArmSmcHyp() {{
> decode_block = '''
> {
> if (bits(machInst, 21))
> {
> return new Smc(machInst);
> } else {
> uint32_t imm16 = (bits(machInst, 19, 8) << 4) |
> (bits(machInst, 3, 0) << 0);
> return new Hvc(machInst, imm16);
> }
> }
> '''
> }};
>
47a68
> const uint8_t sysM = byteMask | (bits(machInst, 8) << 4);
51a73,74
> const bool r = bits(machInst, 22);
> const bool isBanked = bits(machInst, 9);
59c82,86
< return new MrsCpsr(machInst, rd);
---
> if (isBanked) {
> return new MrsBankedReg(machInst, rd, sysM, r!=0);
> } else {
> return new MrsCpsr(machInst, rd);
> }
64c91,95
< return new MsrCpsrReg(machInst, rn, byteMask);
---
> if (isBanked) {
> return new MsrBankedReg(machInst, rn, sysM, r!=0);
> } else {
> return new MsrCpsrReg(machInst, rn, byteMask);
> }
67c98,102
< return new MrsSpsr(machInst, rd);
---
> if (isBanked) {
> return new MrsBankedReg(machInst, rd, sysM, r!=0);
> } else {
> return new MrsSpsr(machInst, rd);
> }
72c107,111
< return new MsrSpsrReg(machInst, rn, byteMask);
---
> if (isBanked) {
> return new MsrBankedReg(machInst, rn, sysM, r!=0);
> } else {
> return new MsrSpsrReg(machInst, rn, byteMask);
> }
102c141
< case NUM_MISCREGS:
---
> case MISCREG_CP14_UNIMPL:
107a147
> uint32_t iss = mcrMrcIssBuild(isRead, crm, rt, crn, opc1, opc2);
109c149
< return new Mrc14(machInst, rt, (IntRegIndex)miscReg);
---
> return new Mrc14(machInst, rt, (IntRegIndex)miscReg, iss);
111c151
< return new Mcr14(machInst, (IntRegIndex)miscReg, rt);
---
> return new Mcr14(machInst, (IntRegIndex)miscReg, rt, iss);
126,127c166,167
< StaticInstPtr
< decodeMcrMrc15(ExtMachInst machInst);
---
> StaticInstPtr decodeMcrMrc14(ExtMachInst machInst);
> StaticInstPtr decodeMcrMrc15(ExtMachInst machInst);
139d178
<
140a180
> uint32_t iss = mcrMrcIssBuild(isRead, crm, rt, crn, opc1, opc2);
145c185
< case NUM_MISCREGS:
---
> case MISCREG_CP15_UNIMPL:
150,158d189
< case MISCREG_DCCISW:
< return new WarnUnimplemented(
< isRead ? "mrc dccisw" : "mcr dcisw", machInst);
< case MISCREG_DCCIMVAC:
< return new WarnUnimplemented(
< isRead ? "mrc dccimvac" : "mcr dccimvac", machInst);
< case MISCREG_DCIMVAC:
< return new WarnUnimplemented(
< isRead ? "mrc dcimvac" : "mcr dcimvac", machInst);
162,164d192
< case MISCREG_DCCMVAU:
< return new WarnUnimplemented(
< isRead ? "mrc dccmvau" : "mcr dccmvau", machInst);
166c194
< return new Isb(machInst);
---
> return new Isb(machInst, iss);
168c196
< return new Dsb(machInst);
---
> return new Dsb(machInst, iss);
170,191c198,203
< return new Dmb(machInst);
< case MISCREG_ICIALLUIS:
< return new WarnUnimplemented(
< isRead ? "mrc icialluis" : "mcr icialluis", machInst);
< case MISCREG_ICIMVAU:
< return new WarnUnimplemented(
< isRead ? "mrc icimvau" : "mcr icimvau", machInst);
< case MISCREG_BPIMVA:
< return new WarnUnimplemented(
< isRead ? "mrc bpimva" : "mcr bpimva", machInst);
< case MISCREG_BPIALLIS:
< return new WarnUnimplemented(
< isRead ? "mrc bpiallis" : "mcr bpiallis", machInst);
< case MISCREG_BPIALL:
< return new WarnUnimplemented(
< isRead ? "mrc bpiall" : "mcr bpiall", machInst);
< case MISCREG_L2LATENCY:
< return new WarnUnimplemented(
< isRead ? "mrc l2latency" : "mcr l2latency", machInst);
< case MISCREG_CRN15:
< return new WarnUnimplemented(
< isRead ? "mrc crn15" : "mcr crn15", machInst);
---
> return new Dmb(machInst, iss);
> default:
> if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
> std::string full_mnem = csprintf("%s %s",
> isRead ? "mrc" : "mcr", miscRegName[miscReg]);
> warn("\\tinstruction '%s' unimplemented\\n", full_mnem);
193,211c205,212
< // Write only.
< case MISCREG_TLBIALLIS:
< case MISCREG_TLBIMVAIS:
< case MISCREG_TLBIASIDIS:
< case MISCREG_TLBIMVAAIS:
< case MISCREG_ITLBIALL:
< case MISCREG_ITLBIMVA:
< case MISCREG_ITLBIASID:
< case MISCREG_DTLBIALL:
< case MISCREG_DTLBIMVA:
< case MISCREG_DTLBIASID:
< case MISCREG_TLBIALL:
< case MISCREG_TLBIMVA:
< case MISCREG_TLBIASID:
< case MISCREG_TLBIMVAA:
< if (isRead) {
< return new Unknown(machInst);
< } else {
< return new Mcr15(machInst, (IntRegIndex)miscReg, rt);
---
> // Remove the warn flag and set the implemented flag. This
> // prevents the instruction warning a second time, it also
> // means the instruction is actually generated. Actually
> // creating the instruction to access an register that isn't
> // implemented sounds a bit silly, but its required to get
> // the correct behaviour for hyp traps and undef exceptions.
> miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true;
> miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false;
214,217c215,218
< // Read only in user mode.
< case MISCREG_TPIDRURO:
< if (isRead) {
< return new Mrc15User(machInst, rt, (IntRegIndex)miscReg);
---
> if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
> if (isRead)
> return new Mrc15(machInst, rt, (IntRegIndex)miscReg, iss);
> return new Mcr15(machInst, (IntRegIndex)miscReg, rt, iss);
219c220,222
< return new Mcr15(machInst, (IntRegIndex)miscReg, rt);
---
> return new FailUnimplemented(csprintf("%s %s",
> isRead ? "mrc" : "mcr", miscRegName[miscReg]).c_str(),
> machInst);
220a224,227
> }
> }
> '''
> }};
222,228c229,233
< // Read/write in user mode.
< case MISCREG_TPIDRURW:
< if (isRead) {
< return new Mrc15User(machInst, rt, (IntRegIndex)miscReg);
< } else {
< return new Mcr15User(machInst, (IntRegIndex)miscReg, rt);
< }
---
> def format McrMrc15() {{
> decode_block = '''
> return decodeMcrMrc15(machInst);
> '''
> }};
230c235,257
< // Read/write, priveleged only.
---
> let {{
> header_output = '''
> StaticInstPtr
> decodeMcrrMrrc15(ExtMachInst machInst);
> '''
> decoder_output = '''
> StaticInstPtr
> decodeMcrrMrrc15(ExtMachInst machInst)
> {
> const uint32_t crm = bits(machInst, 3, 0);
> const uint32_t opc1 = bits(machInst, 7, 4);
> const MiscRegIndex miscReg = decodeCP15Reg64(crm, opc1);
> const IntRegIndex rt = (IntRegIndex) (uint32_t) bits(machInst, 15, 12);
> const IntRegIndex rt2 = (IntRegIndex) (uint32_t) bits(machInst, 19, 16);
>
> const bool isRead = bits(machInst, 20);
>
> switch (miscReg) {
> case MISCREG_CP15_UNIMPL:
> return new FailUnimplemented(
> csprintf("miscreg crm:%d opc1:%d 64-bit %s unknown",
> crm, opc1, isRead ? "read" : "write").c_str(),
> machInst);
232c259,280
< if (miscReg >= MISCREG_CP15_UNIMP_START)
---
> if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
> std::string full_mnem = csprintf("%s %s",
> isRead ? "mrrc" : "mcrr", miscRegName[miscReg]);
> warn("\\tinstruction '%s' unimplemented\\n", full_mnem);
>
> // Remove the warn flag and set the implemented flag. This
> // prevents the instruction warning a second time, it also
> // means the instruction is actually generated. Actually
> // creating the instruction to access an register that isn't
> // implemented sounds a bit silly, but its required to get
> // the correct behaviour for hyp traps and undef exceptions.
> miscRegInfo[miscReg][MISCREG_IMPLEMENTED] = true;
> miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL] = false;
> }
>
> if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
> uint32_t iss = mcrrMrrcIssBuild(isRead, crm, rt, rt2, opc1);
>
> if (isRead)
> return new Mrrc15(machInst, (IntRegIndex) miscReg, rt2, rt, iss);
> return new Mcrr15(machInst, rt2, rt, (IntRegIndex) miscReg, iss);
> } else {
234c282
< isRead ? "mrc" : "mcr", miscRegName[miscReg]).c_str(),
---
> isRead ? "mrrc" : "mcrr", miscRegName[miscReg]).c_str(),
236,239d283
< if (isRead) {
< return new Mrc15(machInst, rt, (IntRegIndex)miscReg);
< } else {
< return new Mcr15(machInst, (IntRegIndex)miscReg, rt);
246c290
< def format McrMrc15() {{
---
> def format Mcrr15() {{
248c292
< return decodeMcrMrc15(machInst);
---
> return decodeMcrrMrrc15(machInst);
250a295,300
>
> def format Mrrc15() {{
> decode_block = '''
> return decodeMcrrMrrc15(machInst);
> '''
> }};