mirror of https://github.com/bsnes-emu/bsnes.git
Update to v103r29 release.
byuu says: Changelog: - processor/arm7tdmi: implementation all nine remaining ARM instructions - processor/arm7tdmi: implemented five more THUMB instructions (sixteen remain)
This commit is contained in:
parent
a72ff8b7fa
commit
559eeccc89
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "103.28";
|
||||
static const string Version = "103.29";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -301,7 +301,7 @@ auto ARM::disassembleInstructionARM(uint32 pc) -> string {
|
|||
|
||||
output.append(opcodes[opcode], conditions[condition]);
|
||||
if(isMove(opcode)) output.append(save ? "s " : " ", registers[rd], ",");
|
||||
if(isComp(opcode)) output.append(registers[rn], ",");
|
||||
if(isComp(opcode)) output.append(" ", registers[rn], ",");
|
||||
if(isMath(opcode)) output.append(save ? "s " : " ", registers[rd], ",", registers[rn], ",");
|
||||
output.append(registers[rm]);
|
||||
if(mode == 0) output.append(" lsl ");
|
||||
|
@ -357,7 +357,7 @@ auto ARM::disassembleInstructionARM(uint32 pc) -> string {
|
|||
if(pre == 1) output.append("]");
|
||||
if(pre == 0 || writeback == 1) output.append("!");
|
||||
|
||||
if(rn == 15) output.append(" =0x", hex(read((byte ? Byte : Word) | Nonsequential, pc + 8 + (up ? +immediate : -immediate)), 8L));
|
||||
if(rn == 15) output.append(" =0x", hex(read((byte ? Byte : Word) | Nonsequential, pc + 8 + (up ? +immediate : -immediate)), byte ? 2L : 4L));
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -496,7 +496,6 @@ auto ARM::arm_op_move_register_offset() {
|
|||
uint32 rd = r(d);
|
||||
uint32 rs = immediate;
|
||||
uint32 rm = r(m);
|
||||
bool c = cpsr().c;
|
||||
|
||||
if(mode == 0) rm = lsl(rm, rs);
|
||||
if(mode == 1) rm = lsr(rm, rs ? rs : (uint32)32);
|
||||
|
|
|
@ -31,7 +31,6 @@ struct ARM7TDMI {
|
|||
struct GPR;
|
||||
struct PSR;
|
||||
inline auto r(uint4) -> GPR&;
|
||||
inline auto u(uint4) -> GPR&;
|
||||
inline auto cpsr() -> PSR&;
|
||||
inline auto spsr() -> PSR&;
|
||||
inline auto privileged() const -> bool;
|
||||
|
@ -67,22 +66,33 @@ struct ARM7TDMI {
|
|||
auto armALU(uint4 mode, uint4 target, uint4 source, uint32 data) -> void;
|
||||
auto armMoveToStatus(uint4 field, uint1 source, uint32 data) -> void;
|
||||
|
||||
auto armInstructionBranch(int24, uint1) -> void;
|
||||
auto armInstructionBranchExchangeRegister(uint4) -> void;
|
||||
auto armInstructionDataImmediate(uint8, uint4, uint4, uint4, uint1, uint4) -> void;
|
||||
auto armInstructionDataImmediateShift(uint4, uint2, uint5, uint4, uint4, uint1, uint4) -> void;
|
||||
auto armInstructionDataRegisterShift(uint4, uint2, uint4, uint4, uint4, uint1, uint4) -> void;
|
||||
auto armInstructionLoadImmediate(uint8, uint1, uint4, uint4, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionLoadRegister(uint4, uint1, uint4, uint4, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMemorySwap(uint4, uint4, uint4, uint1) -> void;
|
||||
auto armInstructionMoveHalfImmediate(uint8, uint4, uint4, uint1, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMoveHalfRegister(uint4, uint4, uint4, uint1, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMoveImmediateOffset(uint12, uint4, uint4, uint1, uint1, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMoveMultiple(uint16, uint4, uint1, uint1, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMoveRegisterOffset(uint4, uint2, uint5, uint4, uint4, uint1, uint1, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionMoveToRegisterFromStatus(uint4, uint1) -> void;
|
||||
auto armInstructionMoveToStatusFromImmediate(uint8, uint4, uint4, uint1) -> void;
|
||||
auto armInstructionMoveToStatusFromRegister(uint4, uint4, uint1) -> void;
|
||||
auto armInstructionMultiply(uint4, uint4, uint4, uint4, uint1, uint1) -> void;
|
||||
auto armInstructionMultiplyLong(uint4, uint4, uint4, uint4, uint1, uint1, uint1) -> void;
|
||||
auto armInstructionSoftwareInterrupt(uint24 immediate) -> void;
|
||||
|
||||
//instructions-thumb.cpp
|
||||
auto thumbALU(uint4 mode, uint4 target, uint4 source) -> void;
|
||||
|
||||
auto thumbInstructionALU(uint3, uint3, uint4) -> void;
|
||||
auto thumbInstructionAdjustImmediate(uint3, uint3, uint3, uint1) -> void;
|
||||
auto thumbInstructionAdjustRegister(uint3, uint3, uint3, uint1) -> void;
|
||||
auto thumbInstructionBranchExchange(uint4) -> void;
|
||||
auto thumbInstructionImmediate(uint8, uint3, uint2) -> void;
|
||||
auto thumbInstructionShiftImmediate(uint3, uint3, uint5, uint2) -> void;
|
||||
|
||||
//serialization.cpp
|
||||
auto serialize(serializer&) -> void;
|
||||
|
@ -210,19 +220,32 @@ struct ARM7TDMI {
|
|||
function<string ()> thumbDisassemble[65536];
|
||||
|
||||
//disassembler.cpp
|
||||
auto armDisassembleBranch(int24, uint1) -> string;
|
||||
auto armDisassembleBranchExchangeRegister(uint4) -> string;
|
||||
auto armDisassembleDataImmediate(uint8, uint4, uint4, uint4, uint1, uint4) -> string;
|
||||
auto armDisassembleDataImmediateShift(uint4, uint2, uint5, uint4, uint4, uint1, uint4) -> string;
|
||||
auto armDisassembleDataRegisterShift(uint4, uint2, uint4, uint4, uint4, uint1, uint4) -> string;
|
||||
auto armDisassembleLoadImmediate(uint8, uint1, uint4, uint4, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleLoadRegister(uint4, uint1, uint4, uint4, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMemorySwap(uint4, uint4, uint4, uint1) -> string;
|
||||
auto armDisassembleMoveHalfImmediate(uint8, uint4, uint4, uint1, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMoveHalfRegister(uint4, uint4, uint4, uint1, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMoveImmediateOffset(uint12, uint4, uint4, uint1, uint1, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMoveMultiple(uint16, uint4, uint1, uint1, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMoveRegisterOffset(uint4, uint2, uint5, uint4, uint4, uint1, uint1, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleMoveToRegisterFromStatus(uint4, uint1) -> string;
|
||||
auto armDisassembleMoveToStatusFromImmediate(uint8, uint4, uint4, uint1) -> string;
|
||||
auto armDisassembleMoveToStatusFromRegister(uint4, uint4, uint1) -> string;
|
||||
auto armDisassembleMultiply(uint4, uint4, uint4, uint4, uint1, uint1) -> string;
|
||||
auto armDisassembleMultiplyLong(uint4, uint4, uint4, uint4, uint1, uint1, uint1) -> string;
|
||||
auto armDisassembleSoftwareInterrupt(uint24) -> string;
|
||||
|
||||
auto thumbDisassembleALU(uint3, uint3, uint4) -> string;
|
||||
auto thumbDisassembleAdjustImmediate(uint3, uint3, uint3, uint1) -> string;
|
||||
auto thumbDisassembleAdjustRegister(uint3, uint3, uint3, uint1) -> string;
|
||||
auto thumbDisassembleBranchExchange(uint4) -> string;
|
||||
auto thumbDisassembleImmediate(uint8, uint3, uint2) -> string;
|
||||
auto thumbDisassembleShiftImmediate(uint3, uint3, uint5, uint2) -> string;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,81 @@
|
|||
static uint32 _pc;
|
||||
static string _c;
|
||||
static string _r[16] = {
|
||||
static const string _r[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"
|
||||
};
|
||||
#define _s save ? "s" : ""
|
||||
|
||||
#define isMove(mode) (mode == 13 || mode == 15)
|
||||
#define isComp(mode) (mode >= 8 && mode <= 11)
|
||||
#define isMath(mode) (mode <= 7 || mode == 12 || mode == 14)
|
||||
|
||||
auto ARM7TDMI::disassemble(uint32 pc) -> string {
|
||||
return "";
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto ARM7TDMI::armDisassembleBranch
|
||||
(int24 displacement, uint1 link) -> string {
|
||||
return {"b", link ? "l" : "", _c, " 0x", hex(_pc + 8 + displacement * 4, 8L)};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleBranchExchangeRegister
|
||||
(uint4 m) -> string {
|
||||
return {"bx", _c, " ", _r[m]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleDataImmediate
|
||||
(uint8 immediate, uint4 shift, uint4 d, uint4 n, uint1 save, uint4 mode) -> string {
|
||||
static const string opcode[] = {
|
||||
"and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc",
|
||||
"tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn",
|
||||
};
|
||||
uint32 data = immediate >> (shift << 1) | immediate << 32 - (shift << 1);
|
||||
return {opcode[mode], _c,
|
||||
isMove(mode) ? string{_s, " ", _r[d]} : string{},
|
||||
isComp(mode) ? string{" ", _r[n]} : string{},
|
||||
isMath(mode) ? string{_s, " ", _r[d], ",", _r[n]} : string{},
|
||||
",#0x", hex(data, 8L)};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleDataImmediateShift
|
||||
(uint4 m, uint2 type, uint5 shift, uint4 d, uint4 n, uint1 save, uint4 mode) -> string {
|
||||
static const string opcode[] = {
|
||||
"and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc",
|
||||
"tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn",
|
||||
};
|
||||
return {opcode[mode], _c,
|
||||
isMove(mode) ? string{_s, " ", _r[d]} : string{},
|
||||
isComp(mode) ? string{" ", _r[n]} : string{},
|
||||
isMath(mode) ? string{_s, " ", _r[d], ",", _r[n]} : string{},
|
||||
",", _r[m],
|
||||
type == 0 && shift ? string{" lsl #", shift} : string{},
|
||||
type == 1 ? string{" lsr #", shift ? (uint)shift : 32} : string{},
|
||||
type == 2 ? string{" asr #", shift ? (uint)shift : 32} : string{},
|
||||
type == 3 && shift ? string{" ror #", shift} : string{},
|
||||
type == 3 && !shift ? " rrx" : ""};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleDataRegisterShift
|
||||
(uint4 m, uint2 type, uint4 s, uint4 d, uint4 n, uint1 save, uint4 mode) -> string {
|
||||
static const string opcode[] = {
|
||||
"and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc",
|
||||
"tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn",
|
||||
};
|
||||
return {opcode[mode], _c,
|
||||
isMove(mode) ? string{_s, " ", _r[d]} : string{},
|
||||
isComp(mode) ? string{" ", _r[n]} : string{},
|
||||
isMath(mode) ? string{_s, " ", _r[d], ",", _r[n]} : string{},
|
||||
",", _r[m], " ",
|
||||
type == 0 ? "lsl" : "",
|
||||
type == 1 ? "lsr" : "",
|
||||
type == 2 ? "asr" : "",
|
||||
type == 3 ? "ror" : "",
|
||||
" ", _r[s]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleLoadImmediate
|
||||
(uint8 immediate, uint1 half, uint4 d, uint4 n, uint1 writeback, uint1 up, uint1 pre) -> string {
|
||||
string data;
|
||||
|
@ -69,6 +128,48 @@ auto ARM7TDMI::armDisassembleMoveHalfRegister
|
|||
pre == 0 || writeback ? "!" : ""};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleMoveImmediateOffset
|
||||
(uint12 immediate, uint4 d, uint4 n, uint1 mode, uint1 writeback, uint1 byte, uint1 up, uint1 pre) -> string {
|
||||
string data;
|
||||
if(n == 15) data = {" =0x", hex(read((byte ? Byte : Word) | Nonsequential,
|
||||
_pc + 8 + (up ? +immediate : -immediate)), byte ? 2L : 4L)};
|
||||
return {mode ? "ldr" : "str", _c, byte ? "b" : "", " ", _r[d], ",[", _r[n],
|
||||
pre == 0 ? "]" : "",
|
||||
immediate ? string{",", up ? "+" : "-", "0x", hex(immediate, 3L)} : string{},
|
||||
pre == 1 ? "]" : "",
|
||||
pre == 0 || writeback ? "!" : "", data};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleMoveMultiple
|
||||
(uint16 list, uint4 n, uint1 mode, uint1 writeback, uint1 type, uint1 up, uint1 pre) -> string {
|
||||
string registers;
|
||||
for(auto index : range(16)) {
|
||||
if(list.bit(index)) registers.append(_r[index], ",");
|
||||
}
|
||||
registers.trimRight(",", 1L);
|
||||
return {mode ? "ldm" : "stm",
|
||||
up == 0 && pre == 0 ? "da" : "",
|
||||
up == 0 && pre == 1 ? "db" : "",
|
||||
up == 1 && pre == 0 ? "ia" : "",
|
||||
up == 1 && pre == 1 ? "ib" : "",
|
||||
" ", _r[n], writeback ? "!" : "",
|
||||
",{", registers, "}", type ? "^" : ""};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleMoveRegisterOffset
|
||||
(uint4 m, uint2 type, uint5 shift, uint4 d, uint4 n, uint1 mode, uint1 writeback, uint1 byte, uint1 up, uint1 pre) -> string {
|
||||
return {mode ? "ldr" : "str", _c, byte ? "b" : "", " ", _r[d], ",[", _r[n],
|
||||
pre == 0 ? "]" : "",
|
||||
",", up ? "+" : "-", _r[m],
|
||||
type == 0 && shift ? string{" lsl #", shift} : string{},
|
||||
type == 1 ? string{" lsr #", shift ? (uint)shift : 32} : string{},
|
||||
type == 2 ? string{" asr #", shift ? (uint)shift : 32} : string{},
|
||||
type == 3 && shift ? string{" ror #", shift} : string{},
|
||||
type == 3 && !shift ? " rrx" : "",
|
||||
pre == 1 ? "]" : "",
|
||||
pre == 0 || writeback ? "!" : ""};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleMoveToRegisterFromStatus
|
||||
(uint4 d, uint1 mode) -> string {
|
||||
return {"mrs", _c, " ", _r[d], ",", mode ? "spsr" : "cpsr"};
|
||||
|
@ -110,9 +211,77 @@ auto ARM7TDMI::armDisassembleMultiplyLong
|
|||
_r[l], ",", _r[h], ",", _r[m], ",", _r[s]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armDisassembleSoftwareInterrupt
|
||||
(uint24 immediate) -> string {
|
||||
return {"swi #0x", hex(immediate, 6L)};
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleALU
|
||||
(uint3 d, uint3 m, uint4 mode) -> string {
|
||||
static const string opcode[] = {
|
||||
"and", "eor", "lsl", "lsr", "asr", "adc", "sbc", "ror",
|
||||
"tst", "neg", "cmp", "cmn", "orr", "mul", "bic", "mvn",
|
||||
};
|
||||
return {opcode[mode], " ", _r[d], ",", _r[m]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleAdjustImmediate
|
||||
(uint3 d, uint3 n, uint3 immediate, uint1 mode) -> string {
|
||||
return {!mode ? "add" : "sub", " ", _r[d], ",", _r[n], ",#", immediate};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleAdjustRegister
|
||||
(uint3 d, uint3 n, uint3 m, uint1 mode) -> string {
|
||||
return {!mode ? "add" : "sub", " ", _r[d], ",", _r[n], ",", _r[m]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleBranchExchange
|
||||
(uint4 m) -> string {
|
||||
return {"bx ", _r[m]};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleImmediate
|
||||
(uint8 immediate, uint3 d, uint2 mode) -> string {
|
||||
static const string opcode[] = {"mov", "cmp", "add", "sub"};
|
||||
return {opcode[mode], " ", _r[d], ",#0x", hex(immediate, 2L)};
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbDisassembleShiftImmediate
|
||||
(uint3 d, uint3 m, uint5 immediate, uint2 mode) -> string {
|
||||
static const string opcode[] = {"lsl", "lsr", "asr"};
|
||||
return {opcode[mode], " ", _r[d], ",", _r[m], ",#", immediate};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,18 @@ auto ARM7TDMI::armInitialize() -> void {
|
|||
#define pattern(s) \
|
||||
std::integral_constant<uint32_t, bit::test(s)>::value
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0,23), /* displacement */ \
|
||||
opcode.bit (24) /* link */
|
||||
for(uint4 displacementLo : range(16))
|
||||
for(uint4 displacementHi : range(16))
|
||||
for(uint1 link : range(2)) {
|
||||
auto opcode = pattern(".... 101? ???? ???? ???? ???? ???? ????")
|
||||
| displacementLo << 4 | displacementHi << 20 | link << 24;
|
||||
bind(opcode, Branch);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3) /* m */
|
||||
{
|
||||
|
@ -74,6 +86,57 @@ auto ARM7TDMI::armInitialize() -> void {
|
|||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 7), /* immediate */ \
|
||||
opcode.bits( 8,11), /* shift */ \
|
||||
opcode.bits(12,15), /* d */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* save */ \
|
||||
opcode.bits(21,24) /* mode */
|
||||
for(uint4 shiftHi : range(16))
|
||||
for(uint1 save : range(2))
|
||||
for(uint4 mode : range(16)) {
|
||||
if(mode >= 8 && mode <= 11 && !save) continue; //TST, TEQ, CMP, CMN
|
||||
auto opcode = pattern(".... 001? ???? ???? ???? ???? ???? ????") | shiftHi << 4 | save << 20 | mode << 21;
|
||||
bind(opcode, DataImmediate);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3), /* m */ \
|
||||
opcode.bits( 5, 6), /* type */ \
|
||||
opcode.bits( 7,11), /* shift */ \
|
||||
opcode.bits(12,15), /* d */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* save */ \
|
||||
opcode.bits(21,24) /* mode */
|
||||
for(uint2 type : range(4))
|
||||
for(uint1 shiftLo : range(2))
|
||||
for(uint1 save : range(2))
|
||||
for(uint4 mode : range(16)) {
|
||||
if(mode >= 8 && mode <= 11 && !save) continue; //TST, TEQ, CMP, CMN
|
||||
auto opcode = pattern(".... 000? ???? ???? ???? ???? ???0 ????") | type << 5 | shiftLo << 7 | save << 20 | mode << 21;
|
||||
bind(opcode, DataImmediateShift);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3), /* m */ \
|
||||
opcode.bits( 5, 6), /* type */ \
|
||||
opcode.bits( 8,11), /* s */ \
|
||||
opcode.bits(12,15), /* d */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* save */ \
|
||||
opcode.bits(21,24) /* mode */
|
||||
for(uint2 type : range(4))
|
||||
for(uint1 save : range(2))
|
||||
for(uint4 mode : range(16)) {
|
||||
if(mode >= 8 && mode <= 11 && !save) continue; //TST, TEQ, CMP, CMN
|
||||
auto opcode = pattern(".... 000? ???? ???? ???? ???? 0??1 ????") | type << 5 | save << 20 | mode << 21;
|
||||
bind(opcode, DataRegisterShift);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3) << 0 | opcode.bits( 8,11) << 4, /* immediate */ \
|
||||
opcode.bit ( 5), /* half */ \
|
||||
|
@ -153,6 +216,71 @@ auto ARM7TDMI::armInitialize() -> void {
|
|||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0,11), /* immediate */ \
|
||||
opcode.bits(12,15), /* d */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* mode */ \
|
||||
opcode.bit (21), /* writeback */ \
|
||||
opcode.bit (22), /* byte */ \
|
||||
opcode.bit (23), /* up */ \
|
||||
opcode.bit (24) /* pre */
|
||||
for(uint4 immediatePart : range(16))
|
||||
for(uint1 mode : range(2))
|
||||
for(uint1 writeback : range(2))
|
||||
for(uint1 byte : range(2))
|
||||
for(uint1 up : range(2))
|
||||
for(uint1 pre : range(2)) {
|
||||
auto opcode = pattern(".... 010? ???? ???? ???? ???? ???? ????")
|
||||
| immediatePart << 4 | mode << 20 | writeback << 21 | byte << 22 | up << 23 | pre << 24;
|
||||
bind(opcode, MoveImmediateOffset);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0,15), /* list */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* mode */ \
|
||||
opcode.bit (21), /* writeback */ \
|
||||
opcode.bit (22), /* type */ \
|
||||
opcode.bit (23), /* up */ \
|
||||
opcode.bit (24) /* pre */
|
||||
for(uint4 listPart : range(16))
|
||||
for(uint1 mode : range(2))
|
||||
for(uint1 writeback : range(2))
|
||||
for(uint1 type : range(2))
|
||||
for(uint1 up : range(2))
|
||||
for(uint1 pre : range(2)) {
|
||||
auto opcode = pattern(".... 100? ???? ???? ???? ???? ???? ????")
|
||||
| listPart << 4 | mode << 20 | writeback << 21 | type << 22 | up << 23 | pre << 24;
|
||||
bind(opcode, MoveMultiple);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3), /* m */ \
|
||||
opcode.bits( 5, 6), /* type */ \
|
||||
opcode.bits( 7,11), /* shift */ \
|
||||
opcode.bits(12,15), /* d */ \
|
||||
opcode.bits(16,19), /* n */ \
|
||||
opcode.bit (20), /* mode */ \
|
||||
opcode.bit (21), /* writeback */ \
|
||||
opcode.bit (22), /* byte */ \
|
||||
opcode.bit (23), /* up */ \
|
||||
opcode.bit (24) /* pre */
|
||||
for(uint2 type : range(4))
|
||||
for(uint1 shiftLo : range(2))
|
||||
for(uint1 mode : range(2))
|
||||
for(uint1 writeback : range(2))
|
||||
for(uint1 byte : range(2))
|
||||
for(uint1 up : range(2))
|
||||
for(uint1 pre : range(2)) {
|
||||
auto opcode = pattern(".... 011? ???? ???? ???? ???? ???0 ????")
|
||||
| type << 5 | shiftLo << 7 | mode << 20 | writeback << 21 | byte << 22 | up << 23 | pre << 24;
|
||||
bind(opcode, MoveRegisterOffset);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0, 3), /* d */ \
|
||||
opcode.bit (22) /* mode */
|
||||
|
@ -214,6 +342,15 @@ auto ARM7TDMI::armInitialize() -> void {
|
|||
}
|
||||
#undef arguments
|
||||
|
||||
#define arguments \
|
||||
opcode.bits( 0,23) /* immediate */
|
||||
for(uint4 immediateLo : range(16))
|
||||
for(uint4 immediateHi : range(16)) {
|
||||
auto opcode = pattern(".... 1111 ???? ???? ???? ???? ???? ????") | immediateLo << 4 | immediateHi << 20;
|
||||
bind(opcode, SoftwareInterrupt);
|
||||
}
|
||||
#undef arguments
|
||||
|
||||
#undef bind
|
||||
#undef pattern
|
||||
}
|
||||
|
@ -228,6 +365,21 @@ auto ARM7TDMI::thumbInitialize() -> void {
|
|||
#define pattern(s) \
|
||||
std::integral_constant<uint16_t, bit::test(s)>::value
|
||||
|
||||
for(uint3 d : range(8))
|
||||
for(uint3 m : range(8))
|
||||
for(uint4 mode : range(16)) {
|
||||
auto opcode = pattern("0100 00?? ???? ????") | d << 0 | m << 3 | mode << 6;
|
||||
bind(opcode, ALU, d, m, mode);
|
||||
}
|
||||
|
||||
for(uint3 d : range(8))
|
||||
for(uint3 n : range(8))
|
||||
for(uint3 immediate : range(8))
|
||||
for(uint1 mode : range(2)) {
|
||||
auto opcode = pattern("0001 11?? ???? ????") | d << 0 | n << 3 | immediate << 6 | mode << 9;
|
||||
bind(opcode, AdjustImmediate, d, n, immediate, mode);
|
||||
}
|
||||
|
||||
for(uint3 d : range(8))
|
||||
for(uint3 n : range(8))
|
||||
for(uint3 m : range(8))
|
||||
|
@ -236,6 +388,49 @@ auto ARM7TDMI::thumbInitialize() -> void {
|
|||
bind(opcode, AdjustRegister, d, n, m, mode);
|
||||
}
|
||||
|
||||
for(uint3 _ : range(8))
|
||||
for(uint4 m : range(16)) {
|
||||
auto opcode = pattern("0100 0111 0??? ?---") | _ << 0 | m << 3;
|
||||
bind(opcode, BranchExchange, m);
|
||||
}
|
||||
|
||||
for(uint8 immediate : range(256))
|
||||
for(uint3 d : range(8))
|
||||
for(uint2 mode : range(4)) {
|
||||
auto opcode = pattern("001? ???? ???? ????") | immediate << 0 | d << 8 | mode << 11;
|
||||
bind(opcode, Immediate, immediate, d, mode);
|
||||
}
|
||||
|
||||
for(uint3 d : range(8))
|
||||
for(uint3 m : range(8))
|
||||
for(uint5 immediate : range(32))
|
||||
for(uint2 mode : range(4)) {
|
||||
if(mode == 3) continue;
|
||||
auto opcode = pattern("000? ???? ???? ????") | d << 0 | m << 3 | immediate << 6 | mode << 11;
|
||||
bind(opcode, ShiftImmediate, d, m, immediate, mode);
|
||||
}
|
||||
|
||||
#undef bind
|
||||
#undef pattern
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,12 @@ auto ARM7TDMI::armMoveToStatus(uint4 field, uint1 mode, uint32 data) -> void {
|
|||
|
||||
//
|
||||
|
||||
auto ARM7TDMI::armInstructionBranch
|
||||
(int24 displacement, uint1 link) -> void {
|
||||
if(link) r(14) = r(15) - 4;
|
||||
r(15) = r(15) + displacement * 4;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionBranchExchangeRegister
|
||||
(uint4 m) -> void {
|
||||
uint32 address = r(m);
|
||||
|
@ -53,6 +59,45 @@ auto ARM7TDMI::armInstructionBranchExchangeRegister
|
|||
r(15) = address;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionDataImmediate
|
||||
(uint8 immediate, uint4 shift, uint4 d, uint4 n, uint1 save, uint4 mode) -> void {
|
||||
uint32 data = immediate;
|
||||
carry = cpsr().c;
|
||||
if(shift) data = ROR(data, shift << 1);
|
||||
armALU(mode, d, n, data);
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionDataImmediateShift
|
||||
(uint4 m, uint2 type, uint5 shift, uint4 d, uint4 n, uint1 save, uint4 mode) -> void {
|
||||
uint32 rm = r(m);
|
||||
carry = cpsr().c;
|
||||
|
||||
switch(type) {
|
||||
case 0: rm = LSL(rm, shift); break;
|
||||
case 1: rm = LSR(rm, shift ? (uint)shift : 32); break;
|
||||
case 2: rm = ASR(rm, shift ? (uint)shift : 32); break;
|
||||
case 3: rm = shift ? ROR(rm, shift) : RRX(rm); break;
|
||||
}
|
||||
|
||||
armALU(mode, d, n, rm);
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionDataRegisterShift
|
||||
(uint4 m, uint2 type, uint4 s, uint4 d, uint4 n, uint1 save, uint4 mode) -> void {
|
||||
uint8 rs = r(s) + (s == 15 ? 4 : 0);
|
||||
uint32 rm = r(m) + (m == 15 ? 4 : 0);
|
||||
carry = cpsr().c;
|
||||
|
||||
switch(type) {
|
||||
case 0: rm = LSL(rm, rs < 33 ? rs : (uint8)33); break;
|
||||
case 1: rm = LSR(rm, rs < 33 ? rs : (uint8)33); break;
|
||||
case 2: rm = ASR(rm, rs < 32 ? rs : (uint8)32); break;
|
||||
case 3: if(rs) rm = ROR(rm, rs & 31 ? rs & 31 : 32); break;
|
||||
}
|
||||
|
||||
armALU(mode, d, n, rm);
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionLoadImmediate
|
||||
(uint8 immediate, uint1 half, uint4 d, uint4 n, uint1 writeback, uint1 up, uint1 pre) -> void {
|
||||
uint32 rn = r(n);
|
||||
|
@ -116,6 +161,87 @@ auto ARM7TDMI::armInstructionMoveHalfRegister
|
|||
if(mode == 1) r(d) = rd;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionMoveImmediateOffset
|
||||
(uint12 immediate, uint4 d, uint4 n, uint1 mode, uint1 writeback, uint1 byte, uint1 up, uint1 pre) -> void {
|
||||
uint32 rn = r(n);
|
||||
uint32 rd = r(d);
|
||||
|
||||
if(pre == 1) rn = up ? rn + immediate : rn - immediate;
|
||||
if(mode == 1) rd = load((byte ? Byte : Word) | Nonsequential, rn);
|
||||
if(mode == 0) store((byte ? Byte : Word) | Nonsequential, rn, rd);
|
||||
if(pre == 0) rn = up ? rn + immediate : rn - immediate;
|
||||
|
||||
if(pre == 0 || writeback) r(n) = rn;
|
||||
if(mode == 1) r(d) = rd;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionMoveMultiple
|
||||
(uint16 list, uint4 n, uint1 mode, uint1 writeback, uint1 type, uint1 up, uint1 pre) -> void {
|
||||
uint32 rn = r(n);
|
||||
if(pre == 0 && up == 1) rn = rn + 0; //IA
|
||||
if(pre == 1 && up == 1) rn = rn + 4; //IB
|
||||
if(pre == 1 && up == 0) rn = rn - bit::count(list) * 4 + 0; //DB
|
||||
if(pre == 0 && up == 0) rn = rn - bit::count(list) * 4 + 4; //DA
|
||||
|
||||
if(writeback && mode == 1) {
|
||||
if(up == 1) r(n) = r(n) + bit::count(list) * 4; //IA,IB
|
||||
if(up == 0) r(n) = r(n) - bit::count(list) * 4; //DA,DB
|
||||
}
|
||||
|
||||
auto cpsrMode = cpsr().m;
|
||||
bool usr = false;
|
||||
if(type && mode == 1 && !list.bit(15)) usr = true;
|
||||
if(type && mode == 0) usr = true;
|
||||
if(usr) cpsr().m = PSR::USR;
|
||||
|
||||
uint sequential = Nonsequential;
|
||||
for(uint m : range(16)) {
|
||||
if(!list.bit(m)) continue;
|
||||
if(mode == 1) r(m) = read(Word | sequential, rn);
|
||||
if(mode == 0) write(Word | sequential, rn, r(m));
|
||||
rn += 4;
|
||||
sequential = Sequential;
|
||||
}
|
||||
|
||||
if(usr) cpsr().m = cpsrMode;
|
||||
|
||||
if(mode) {
|
||||
idle();
|
||||
if(type && list.bit(15) && cpsr().m != PSR::USR && cpsr().m != PSR::SYS) {
|
||||
cpsr() = spsr();
|
||||
}
|
||||
} else {
|
||||
pipeline.nonsequential = true;
|
||||
}
|
||||
|
||||
if(writeback && mode == 0) {
|
||||
if(up == 1) r(n) = r(n) + bit::count(list) * 4; //IA,IB
|
||||
if(up == 0) r(n) = r(n) - bit::count(list) * 4; //DA,DB
|
||||
}
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionMoveRegisterOffset
|
||||
(uint4 m, uint2 type, uint5 shift, uint4 d, uint4 n, uint1 mode, uint1 writeback, uint1 byte, uint1 up, uint1 pre) -> void {
|
||||
uint32 rm = r(m);
|
||||
uint32 rd = r(d);
|
||||
uint32 rn = r(n);
|
||||
|
||||
switch(type) {
|
||||
case 0: rm = LSL(rm, shift); break;
|
||||
case 1: rm = LSR(rm, shift ? (uint)shift : 32); break;
|
||||
case 2: rm = ASR(rm, shift ? (uint)shift : 32); break;
|
||||
case 3: rm = shift ? ROR(rm, shift) : RRX(rm); break;
|
||||
}
|
||||
|
||||
if(pre == 1) rn = up ? rn + rm : rn - rm;
|
||||
if(mode == 1) rd = load((byte ? Byte : Word) | Nonsequential, rn);
|
||||
if(mode == 0) store((byte ? Byte : Word) | Nonsequential, rn, rd);
|
||||
if(pre == 0) rn = up ? rn + rm : rn - rm;
|
||||
|
||||
if(pre == 0 || writeback) r(n) = rn;
|
||||
if(mode == 1) r(d) = rd;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionMoveToRegisterFromStatus
|
||||
(uint4 d, uint1 mode) -> void {
|
||||
if(mode && (cpsr().m == PSR::USR || cpsr().m == PSR::SYS)) return;
|
||||
|
@ -172,3 +298,8 @@ auto ARM7TDMI::armInstructionMultiplyLong
|
|||
cpsr().n = rd.bit(63);
|
||||
}
|
||||
}
|
||||
|
||||
auto ARM7TDMI::armInstructionSoftwareInterrupt
|
||||
(uint24 immediate) -> void {
|
||||
interrupt(PSR::SVC, 0x08);
|
||||
}
|
||||
|
|
|
@ -1,30 +1,63 @@
|
|||
auto ARM7TDMI::thumbALU(uint4 mode, uint4 target, uint4 source) -> void {
|
||||
auto ARM7TDMI::thumbInstructionALU
|
||||
(uint3 d, uint3 m, uint4 mode) -> void {
|
||||
switch(mode) {
|
||||
case 0: r(target) = BIT(r(target) & r(source)); break; //AND
|
||||
case 1: r(target) = BIT(r(target) ^ r(source)); break; //EOR
|
||||
case 2: r(target) = BIT(LSL(r(target), r(source))); break; //LSL
|
||||
case 3: r(target) = BIT(LSR(r(target), r(source))); break; //LSR
|
||||
case 4: r(target) = BIT(ASR(r(target), r(source))); break; //ASR
|
||||
case 5: r(target) = ADD(r(target), r(source), cpsr().c); break; //ADC
|
||||
case 6: r(target) = SUB(r(target), r(source), cpsr().c); break; //SBC
|
||||
case 7: r(target) = BIT(ROR(r(target), r(source))); break; //ROR
|
||||
case 8: BIT(r(target) & r(source)); break; //TST
|
||||
case 9: r(target) = SUB(0, r(source), 1); break; //NEG
|
||||
case 10: SUB(r(target), r(source), 1); break; //CMP
|
||||
case 11: ADD(r(target), r(source), 0); break; //CMN
|
||||
case 12: r(target) = BIT(r(target) | r(source)); break; //ORR
|
||||
case 13: r(target) = MUL(0, r(source), r(target)); break; //MUL
|
||||
case 14: r(target) = BIT(r(target) & ~r(source)); break; //BIC
|
||||
case 15: r(target) = BIT(~r(source)); break; //MVN
|
||||
case 0: r(d) = BIT(r(d) & r(m)); break; //AND
|
||||
case 1: r(d) = BIT(r(d) ^ r(m)); break; //EOR
|
||||
case 2: r(d) = BIT(LSL(r(d), r(m))); break; //LSL
|
||||
case 3: r(d) = BIT(LSR(r(d), r(m))); break; //LSR
|
||||
case 4: r(d) = BIT(ASR(r(d), r(m))); break; //ASR
|
||||
case 5: r(d) = ADD(r(d), r(m), cpsr().c); break; //ADC
|
||||
case 6: r(d) = SUB(r(d), r(m), cpsr().c); break; //SBC
|
||||
case 7: r(d) = BIT(ROR(r(d), r(m))); break; //ROR
|
||||
case 8: BIT(r(d) & r(m)); break; //TST
|
||||
case 9: r(d) = SUB(0, r(m), 1); break; //NEG
|
||||
case 10: SUB(r(d), r(m), 1); break; //CMP
|
||||
case 11: ADD(r(d), r(m), 0); break; //CMN
|
||||
case 12: r(d) = BIT(r(d) | r(m)); break; //ORR
|
||||
case 13: r(d) = MUL(0, r(m), r(d)); break; //MUL
|
||||
case 14: r(d) = BIT(r(d) & ~r(m)); break; //BIC
|
||||
case 15: r(d) = BIT(~r(m)); break; //MVN
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
auto ARM7TDMI::thumbInstructionAdjustImmediate
|
||||
(uint3 d, uint3 n, uint3 immediate, uint1 mode) -> void {
|
||||
switch(mode) {
|
||||
case 0: r(d) = ADD(r(n), immediate, 0); break; //ADD
|
||||
case 1: r(d) = SUB(r(n), immediate, 1); break; //SUB
|
||||
}
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbInstructionAdjustRegister
|
||||
(uint3 d, uint3 n, uint3 m, uint1 mode) -> void {
|
||||
switch(mode) {
|
||||
case 0: r(d) = ADD(r(n), r(m), 0); break;
|
||||
case 1: r(d) = SUB(r(n), r(m), 1); break;
|
||||
case 0: r(d) = ADD(r(n), r(m), 0); break; //ADD
|
||||
case 1: r(d) = SUB(r(n), r(m), 1); break; //SUB
|
||||
}
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbInstructionBranchExchange
|
||||
(uint4 m) -> void {
|
||||
uint32 address = r(m);
|
||||
cpsr().t = address.bit(0);
|
||||
r(15) = address;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbInstructionImmediate
|
||||
(uint8 immediate, uint3 d, uint2 mode) -> void {
|
||||
switch(mode) {
|
||||
case 0: r(d) = BIT(immediate); break; //MOV
|
||||
case 1: SUB(r(d), immediate, 1); break; //CMP
|
||||
case 2: r(d) = ADD(r(d), immediate, 0); break; //ADD
|
||||
case 3: r(d) = SUB(r(d), immediate, 1); break; //SUB
|
||||
}
|
||||
}
|
||||
|
||||
auto ARM7TDMI::thumbInstructionShiftImmediate
|
||||
(uint3 d, uint3 m, uint5 immediate, uint2 mode) -> void {
|
||||
switch(mode) {
|
||||
case 0: r(d) = BIT(LSL(r(m), immediate)); break; //LSL
|
||||
case 1: r(d) = BIT(LSR(r(m), immediate ? (uint)immediate : 32)); break; //LSR
|
||||
case 2: r(d) = BIT(ASR(r(m), immediate ? (uint)immediate : 32)); break; //ASR
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,28 +34,6 @@ auto ARM7TDMI::r(uint4 index) -> GPR& {
|
|||
unreachable;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::u(uint4 index) -> GPR& {
|
||||
switch(index) {
|
||||
case 0: return processor.r0;
|
||||
case 1: return processor.r1;
|
||||
case 2: return processor.r2;
|
||||
case 3: return processor.r3;
|
||||
case 4: return processor.r4;
|
||||
case 5: return processor.r5;
|
||||
case 6: return processor.r6;
|
||||
case 7: return processor.r7;
|
||||
case 8: return processor.r8;
|
||||
case 9: return processor.r9;
|
||||
case 10: return processor.r10;
|
||||
case 11: return processor.r11;
|
||||
case 12: return processor.r12;
|
||||
case 13: return processor.r13;
|
||||
case 14: return processor.r14;
|
||||
case 15: return processor.r15;
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto ARM7TDMI::cpsr() -> PSR& {
|
||||
return processor.cpsr;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue