diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 44ed7dedf7..0b49521e09 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -109,7 +109,11 @@ struct FileListener : LogListener if (mPrependChannelName) { text.insert(0, gTypeNameTable[static_cast(msg.mType)].mName); - + + if (msg.mType == Log::TTY) + { + text = fmt::escape(text) + "\n"; + } } mFile.Write(text); } diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 6ae236b922..a4a43b8624 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -179,7 +179,7 @@ std::string fmt::replace_all(const std::string &src, const std::string& from, co pos += to.length(); } - return src; + return target; } //TODO: move this wx Stuff somewhere else @@ -339,3 +339,34 @@ std::string fmt::tolower(std::string source) return source; } + +std::string fmt::toupper(std::string source) +{ + std::transform(source.begin(), source.end(), source.begin(), ::toupper); + + return source; +} + +std::string fmt::escape(std::string source) +{ + const std::pair escape_list[] = + { + { "\\", "\\\\" }, + { "\a", "\\a" }, + { "\b", "\\b" }, + { "\f", "\\f" }, + { "\n", "\\n" }, + { "\r", "\\r" }, + { "\t", "\\t" }, + { "\v", "\\v" }, + }; + + source = fmt::replace_all(source, escape_list); + + for (char c = 0; c < 32; c++) + { + source = fmt::replace_all(source, std::string(1, c), fmt::Format("\\x%02X", c)); + } + + return source; +} diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index bd4059ab86..4015d5077b 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -579,4 +579,6 @@ namespace fmt std::string merge(std::vector source, const std::string& separator); std::string merge(std::initializer_list> sources, const std::string& separator); std::string tolower(std::string source); + std::string toupper(std::string source); + std::string escape(std::string source); } diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp index f143458d48..cbc6a5d553 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp @@ -30,137 +30,147 @@ struct ARMv7_opcode_t const ARMv7_opcode_t ARMv7_opcode_table[] = { - ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK), // "Undefined" Thumb opcode used + ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK, nullptr), // "Undefined" Thumb opcode used ARMv7_OP4(0x0ff0, 0x00f0, 0x0070, 0x0090, A1, HACK), // "Undefined" ARM opcode used - ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM, nullptr), ARMv7_OP4(0x0fe0, 0x0000, 0x02a0, 0x0000, A1, ADC_IMM), - ARMv7_OP2(0xffc0, 0x4040, T1, ADC_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xeb40, 0x0000, T2, ADC_REG), + ARMv7_OP2(0xffc0, 0x4040, T1, ADC_REG, nullptr), + ARMv7_OP4(0xffe0, 0x8000, 0xeb40, 0x0000, T2, ADC_REG, nullptr), ARMv7_OP4(0x0fe0, 0x0010, 0x00a0, 0x0000, A1, ADC_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x00a0, 0x0010, A1, ADC_RSR), - ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM), - ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM), + ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM, nullptr), + ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM, nullptr), ARMv7_OP4(0xfbe0, 0x8000, 0xf100, 0x0000, T3, ADD_IMM, SKIP_IF( (BF(8, 11) == 15 && BT(20)) || BF(16, 19) == 13 )), ARMv7_OP4(0xfbf0, 0x8000, 0xf200, 0x0000, T4, ADD_IMM, SKIP_IF( (BF(16, 19) & 13) == 13 )), ARMv7_OP4(0x0fe0, 0x0000, 0x0280, 0x0000, A1, ADD_IMM), - ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG), + ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG, nullptr), ARMv7_OP2(0xff00, 0x4400, T2, ADD_REG, SKIP_IF( (c & 0x87) == 0x85 || BF(3, 6) == 13 )), ARMv7_OP4(0xffe0, 0x8000, 0xeb00, 0x0000, T3, ADD_REG, SKIP_IF( (BF(8, 11) == 15 && BT(20)) || BF(16, 19) == 13 )), ARMv7_OP4(0x0fe0, 0x0010, 0x0080, 0x0000, A1, ADD_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x0080, 0x0010, A1, ADD_RSR), - ARMv7_OP2(0xf800, 0xa800, T1, ADD_SPI), - ARMv7_OP2(0xff80, 0xb000, T2, ADD_SPI), + ARMv7_OP2(0xf800, 0xa800, T1, ADD_SPI, nullptr), + ARMv7_OP2(0xff80, 0xb000, T2, ADD_SPI, nullptr), ARMv7_OP4(0xfbef, 0x8000, 0xf10d, 0x0000, T3, ADD_SPI, SKIP_IF( BF(8, 11) == 15 && BT(20) )), - ARMv7_OP4(0xfbff, 0x8000, 0xf20d, 0x0000, T4, ADD_SPI), + ARMv7_OP4(0xfbff, 0x8000, 0xf20d, 0x0000, T4, ADD_SPI, nullptr), ARMv7_OP4(0x0fef, 0x0000, 0x028d, 0x0000, A1, ADD_SPI), - ARMv7_OP2(0xff78, 0x4468, T1, ADD_SPR), + ARMv7_OP2(0xff78, 0x4468, T1, ADD_SPR, nullptr), ARMv7_OP2(0xff87, 0x4485, T2, ADD_SPR, SKIP_IF( BF(3, 6) == 13 )), - ARMv7_OP4(0xffef, 0x8000, 0xeb0d, 0x0000, T3, ADD_SPR), + ARMv7_OP4(0xffef, 0x8000, 0xeb0d, 0x0000, T3, ADD_SPR, nullptr), ARMv7_OP4(0x0fef, 0x0010, 0x008d, 0x0000, A1, ADD_SPR), - ARMv7_OP2(0xf800, 0xa000, T1, ADR), - ARMv7_OP4(0xfbff, 0x8000, 0xf2af, 0x0000, T2, ADR), - ARMv7_OP4(0xfbff, 0x8000, 0xf20f, 0x0000, T3, ADR), + ARMv7_OP2(0xf800, 0xa000, T1, ADR, nullptr), + ARMv7_OP4(0xfbff, 0x8000, 0xf2af, 0x0000, T2, ADR, nullptr), + ARMv7_OP4(0xfbff, 0x8000, 0xf20f, 0x0000, T3, ADR, nullptr), ARMv7_OP4(0x0fff, 0x0000, 0x028f, 0x0000, A1, ADR), ARMv7_OP4(0x0fff, 0x0000, 0x024f, 0x0000, A2, ADR), - ARMv7_OP4(0xfbe0, 0x8000, 0xf000, 0x0000, T1, AND_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf000, 0x0000, T1, AND_IMM, SKIP_IF( BF(8, 11) == 15 && BT(20) )), ARMv7_OP4(0x0fe0, 0x0000, 0x0200, 0x0000, A1, AND_IMM), - ARMv7_OP2(0xffc0, 0x4000, T1, AND_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea00, 0x0000, T2, AND_REG), + ARMv7_OP2(0xffc0, 0x4000, T1, AND_REG, nullptr), + ARMv7_OP4(0xffe0, 0x8000, 0xea00, 0x0000, T2, AND_REG, SKIP_IF( BF(8, 11) == 15 && BT(20) )), ARMv7_OP4(0x0fe0, 0x0010, 0x0000, 0x0000, A1, AND_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x0000, 0x0010, A1, AND_RSR), - ARMv7_OP2(0xf800, 0x1000, T1, ASR_IMM), - ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0020, T2, ASR_IMM), + ARMv7_OP2(0xf800, 0x1000, T1, ASR_IMM, nullptr), + ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0020, T2, ASR_IMM, nullptr), ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0040, A1, ASR_IMM), - ARMv7_OP2(0xffc0, 0x4100, T1, ASR_REG), - ARMv7_OP4(0xffe0, 0xf0f0, 0xfa40, 0xf000, T2, ASR_REG), + ARMv7_OP2(0xffc0, 0x4100, T1, ASR_REG, nullptr), + ARMv7_OP4(0xffe0, 0xf0f0, 0xfa40, 0xf000, T2, ASR_REG, nullptr), ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0050, A1, ASR_REG), - ARMv7_OP2(0xf000, 0xd000, T1, B), - ARMv7_OP2(0xf800, 0xe000, T2, B), - ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x8000, T3, B), - ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x9000, T4, B), + ARMv7_OP2(0xf000, 0xd000, T1, B, SKIP_IF( BF(9, 11) == 0x7 )), + ARMv7_OP2(0xf800, 0xe000, T2, B, nullptr), + ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x8000, T3, B, SKIP_IF( BF(23, 25) == 0x7 )), + ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x9000, T4, B, nullptr), ARMv7_OP4(0x0f00, 0x0000, 0x0a00, 0x0000, A1, B), - ARMv7_OP4(0xffff, 0x8020, 0xf36f, 0x0000, T1, BFC), + ARMv7_OP4(0xffff, 0x8020, 0xf36f, 0x0000, T1, BFC, nullptr), ARMv7_OP4(0x0fe0, 0x007f, 0x07c0, 0x001f, A1, BFC), - ARMv7_OP4(0xfff0, 0x8020, 0xf360, 0x0000, T1, BFI), + + ARMv7_OP4(0xfff0, 0x8020, 0xf360, 0x0000, T1, BFI, SKIP_IF( BF(16, 19) == 15 )), ARMv7_OP4(0x0fe0, 0x0070, 0x07c0, 0x0010, A1, BFI), - ARMv7_OP4(0xfbe0, 0x8000, 0xf020, 0x0000, T1, BIC_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf020, 0x0000, T1, BIC_IMM, nullptr), ARMv7_OP4(0x0fe0, 0x0000, 0x03c0, 0x0000, A1, BIC_IMM), - ARMv7_OP2(0xffc0, 0x4380, T1, BIC_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea20, 0x0000, T2, BIC_REG), + ARMv7_OP2(0xffc0, 0x4380, T1, BIC_REG, nullptr), + ARMv7_OP4(0xffe0, 0x8000, 0xea20, 0x0000, T2, BIC_REG, nullptr), ARMv7_OP4(0x0fe0, 0x0010, 0x01c0, 0x0000, A1, BIC_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x01c0, 0x0010, A1, BIC_RSR), - ARMv7_OP2(0xff00, 0xbe00, T1, BKPT), + ARMv7_OP2(0xff00, 0xbe00, T1, BKPT, nullptr), ARMv7_OP4(0x0ff0, 0x00f0, 0x0120, 0x0070, A1, BKPT), - ARMv7_OP4(0xf800, 0xd000, 0xf000, 0xd000, T1, BL), + ARMv7_OP4(0xf800, 0xd000, 0xf000, 0xd000, T1, BL, nullptr), ARMv7_OP4(0x0f00, 0x0000, 0x0b00, 0x0000, A1, BL), - ARMv7_OP2(0xff80, 0x4780, T1, BLX), - ARMv7_OP4(0xf800, 0xc001, 0xf000, 0xc000, T2, BLX), + ARMv7_OP2(0xff80, 0x4780, T1, BLX, nullptr), + ARMv7_OP4(0xf800, 0xc001, 0xf000, 0xc000, T2, BLX, nullptr), ARMv7_OP4(0x0fff, 0xfff0, 0x012f, 0xff30, A1, BLX), ARMv7_OP4(0xfe00, 0x0000, 0xfa00, 0x0000, A2, BLX), - ARMv7_OP2(0xff87, 0x4700, T1, BX), + ARMv7_OP2(0xff87, 0x4700, T1, BX, nullptr), ARMv7_OP4(0x0fff, 0xfff0, 0x012f, 0xff10, A1, BX), - ARMv7_OP2(0xf500, 0xb100, T1, CB_Z), + ARMv7_OP2(0xf500, 0xb100, T1, CB_Z, nullptr), - ARMv7_OP4(0xfff0, 0xf0f0, 0xfab0, 0xf080, T1, CLZ), + ARMv7_OP4(0xfff0, 0xf0f0, 0xfab0, 0xf080, T1, CLZ, nullptr), ARMv7_OP4(0x0fff, 0x0ff0, 0x016f, 0x0f10, A1, CLZ), - ARMv7_OP4(0xfbf0, 0x8f00, 0xf110, 0x0f00, T1, CMN_IMM), + ARMv7_OP4(0xfbf0, 0x8f00, 0xf110, 0x0f00, T1, CMN_IMM, nullptr), ARMv7_OP4(0x0ff0, 0xf000, 0x0370, 0x0000, A1, CMN_IMM), - ARMv7_OP2(0xffc0, 0x42c0, T1, CMN_REG), - ARMv7_OP4(0xfff0, 0x8f00, 0xeb10, 0x0f00, T2, CMN_REG), + ARMv7_OP2(0xffc0, 0x42c0, T1, CMN_REG, nullptr), + ARMv7_OP4(0xfff0, 0x8f00, 0xeb10, 0x0f00, T2, CMN_REG, nullptr), ARMv7_OP4(0x0ff0, 0xf010, 0x0170, 0x0000, A1, CMN_REG), ARMv7_OP4(0x0ff0, 0xf090, 0x0170, 0x0010, A1, CMN_RSR), - ARMv7_OP2(0xf800, 0x2800, T1, CMP_IMM), - ARMv7_OP4(0xfbf0, 0x8f00, 0xf1b0, 0x0f00, T2, CMP_IMM), + ARMv7_OP2(0xf800, 0x2800, T1, CMP_IMM, nullptr), + ARMv7_OP4(0xfbf0, 0x8f00, 0xf1b0, 0x0f00, T2, CMP_IMM, nullptr), ARMv7_OP4(0x0ff0, 0xf000, 0x0350, 0x0000, A1, CMP_IMM), - ARMv7_OP2(0xffc0, 0x4280, T1, CMP_REG), - ARMv7_OP2(0xff00, 0x4500, T2, CMP_REG), - ARMv7_OP4(0xfff0, 0x8f00, 0xebb0, 0x0f00, T3, CMP_REG), + ARMv7_OP2(0xffc0, 0x4280, T1, CMP_REG, nullptr), + ARMv7_OP2(0xff00, 0x4500, T2, CMP_REG, nullptr), + ARMv7_OP4(0xfff0, 0x8f00, 0xebb0, 0x0f00, T3, CMP_REG, nullptr), ARMv7_OP4(0x0ff0, 0xf010, 0x0150, 0x0000, A1, CMP_REG), ARMv7_OP4(0x0ff0, 0xf090, 0x0150, 0x0010, A1, CMP_RSR), - ARMv7_OP4(0xfbe0, 0x8000, 0xf080, 0x0000, T1, EOR_IMM), + ARMv7_OP4(0xffff, 0xfff0, 0xf3af, 0x80f0, T1, DBG, nullptr), + ARMv7_OP4(0x0fff, 0xfff0, 0x0320, 0xf0f0, A1, DBG), + + ARMv7_OP4(0xffff, 0xfff0, 0xf3bf, 0x8f50, T1, DMB, nullptr), + ARMv7_OP4(0xffff, 0xfff0, 0xf57f, 0xf050, A1, DMB), + + ARMv7_OP4(0xffff, 0xfff0, 0xf3bf, 0x8f40, T1, DSB, nullptr), + ARMv7_OP4(0xffff, 0xfff0, 0xf57f, 0xf040, A1, DSB), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf080, 0x0000, T1, EOR_IMM, SKIP_IF( BF(8, 11) == 15 && BT(20) )), ARMv7_OP4(0x0fe0, 0x0000, 0x0220, 0x0000, A1, EOR_IMM), - ARMv7_OP2(0xffc0, 0x4040, T1, EOR_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea80, 0x0000, T2, EOR_REG), + ARMv7_OP2(0xffc0, 0x4040, T1, EOR_REG, nullptr), + ARMv7_OP4(0xffe0, 0x8000, 0xea80, 0x0000, T2, EOR_REG, SKIP_IF( BF(8, 11) == 15 && BT(20) )), ARMv7_OP4(0x0fe0, 0x0010, 0x0020, 0x0000, A1, EOR_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x0020, 0x0010, A1, EOR_RSR), ARMv7_OP2(0xff00, 0xbf00, T1, IT, SKIP_IF( BF(0, 3) == 0 )), - ARMv7_OP2(0xf800, 0xc800, T1, LDM), - ARMv7_OP4(0xffd0, 0x2000, 0xe890, 0x0000, T2, LDM), + ARMv7_OP2(0xf800, 0xc800, T1, LDM, nullptr), + ARMv7_OP4(0xffd0, 0x2000, 0xe890, 0x0000, T2, LDM, SKIP_IF( BT(21) && BF(16, 19) == 13 )), ARMv7_OP4(0x0fd0, 0x0000, 0x0890, 0x0000, A1, LDM), ARMv7_OP4(0x0fd0, 0x0000, 0x0810, 0x0000, A1, LDMDA), - ARMv7_OP4(0xffd0, 0x2000, 0xe910, 0x0000, T1, LDMDB), + ARMv7_OP4(0xffd0, 0x2000, 0xe910, 0x0000, T1, LDMDB, nullptr), ARMv7_OP4(0x0fd0, 0x0000, 0x0910, 0x0000, A1, LDMDB), ARMv7_OP4(0x0fd0, 0x0000, 0x0990, 0x0000, A1, LDMIB), - ARMv7_OP2(0xf800, 0x6800, T1, LDR_IMM), - ARMv7_OP2(0xf800, 0x9800, T2, LDR_IMM), + ARMv7_OP2(0xf800, 0x6800, T1, LDR_IMM, nullptr), + ARMv7_OP2(0xf800, 0x9800, T2, LDR_IMM, nullptr), ARMv7_OP4(0xfff0, 0x0000, 0xf8d0, 0x0000, T3, LDR_IMM, SKIP_IF( BF(16, 19) == 15 )), ARMv7_OP4(0xfff0, 0x0800, 0xf850, 0x0800, T4, LDR_IMM, SKIP_IF( BF(16, 19) == 15 || BF(8, 10) == 6 || (c & 0xf07ff) == 0xd0304 || (c & 0x500) == 0 )), ARMv7_OP4(0x0e50, 0x0000, 0x0410, 0x0000, A1, LDR_IMM), - ARMv7_OP2(0xf800, 0x4800, T1, LDR_LIT), - ARMv7_OP4(0xff7f, 0x0000, 0xf85f, 0x0000, T2, LDR_LIT), + ARMv7_OP2(0xf800, 0x4800, T1, LDR_LIT, nullptr), + ARMv7_OP4(0xff7f, 0x0000, 0xf85f, 0x0000, T2, LDR_LIT, nullptr), ARMv7_OP4(0x0f7f, 0x0000, 0x051f, 0x0000, A1, LDR_LIT), - ARMv7_OP2(0xfe00, 0x5800, T1, LDR_REG), - ARMv7_OP4(0xfff0, 0x0fc0, 0xf850, 0x0000, T2, LDR_REG), + ARMv7_OP2(0xfe00, 0x5800, T1, LDR_REG, nullptr), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf850, 0x0000, T2, LDR_REG, SKIP_IF( BF(16, 19) == 15 )), ARMv7_OP4(0x0e50, 0x0010, 0x0610, 0x0000, A1, LDR_REG), - + ARMv7_OP2(0xf800, 0x7800, T1, LDRB_IMM), ARMv7_OP4(0xfff0, 0x0000, 0xf890, 0x0000, T2, LDRB_IMM), ARMv7_OP4(0xfff0, 0x0800, 0xf810, 0x0800, T3, LDRB_IMM), @@ -280,7 +290,7 @@ const ARMv7_opcode_t ARMv7_opcode_table[] = ARMv7_OP4(0xfbe0, 0x8000, 0xf040, 0x0000, T1, ORR_IMM), ARMv7_OP4(0x0fe0, 0x0000, 0x0380, 0x0000, A1, ORR_IMM), ARMv7_OP2(0xffc0, 0x4300, T1, ORR_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea40, 0x0000, T2, ORR_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xea40, 0x0000, T2, ORR_REG, SKIP_IF( BF(16, 19) == 15 )), ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR), diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index 94c5f79e83..aede0d0488 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -402,11 +402,51 @@ void ARMv7_instrs::ADC_IMM(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::ADC_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, n, m, shift_t, shift_n; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = n = (code.data & 0x7); + m = (code.data & 0x38) >> 3; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); + + reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry, overflow; + const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); + const u32 result = AddWithCarry(context.read_gpr(n), shifted, context.APSR.C, carry, overflow); + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + context.APSR.V = overflow; + } + } } void ARMv7_instrs::ADC_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -1359,6 +1399,34 @@ void ARMv7_instrs::CMP_RSR(ARMv7Context& context, const ARMv7Code code, const AR } +void ARMv7_instrs::DBG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) +{ + switch (type) + { + case A1: throw __FUNCTION__; + default: throw __FUNCTION__; + } +} + +void ARMv7_instrs::DMB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) +{ + switch (type) + { + case A1: throw __FUNCTION__; + default: throw __FUNCTION__; + } +} + +void ARMv7_instrs::DSB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) +{ + switch (type) + { + case A1: throw __FUNCTION__; + default: throw __FUNCTION__; + } +} + + void ARMv7_instrs::EOR_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { switch (type) @@ -2541,11 +2609,49 @@ void ARMv7_instrs::MVN_IMM(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::MVN_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, m, shift_t, shift_n; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0x7); + m = (code.data & 0x38) >> 3; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); + + reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry; + const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); + const u32 result = ~shifted; + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } void ARMv7_instrs::MVN_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -2646,11 +2752,51 @@ void ARMv7_instrs::ORR_IMM(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::ORR_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, n, m, shift_t, shift_n; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = n = (code.data & 0x7); + m = (code.data & 0x38) >> 3; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); + + reject(n == 15, "ROR (immediate)"); + reject(d == 13 || d == 15 || n == 13 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry; + const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); + const u32 result = context.read_gpr(n) | shifted; + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } void ARMv7_instrs::ORR_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -2936,20 +3082,84 @@ void ARMv7_instrs::REVSH(ARMv7Context& context, const ARMv7Code code, const ARMv void ARMv7_instrs::ROR_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + u32 cond, d, m, shift_n; + bool set_flags; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + const u32 shift_t = DecodeImmShift(3, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); + + reject(shift_t == SRType_RRX, "RRX"); + reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry; + const u32 result = Shift_C(context.read_gpr(m), SRType_ROR, shift_n, context.APSR.C, carry); + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } void ARMv7_instrs::ROR_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, n, m; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = n = (code.data & 0x7); + m = (code.data & 0x38) >> 3; + break; + } + case T2: + { + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + + reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry; + const u32 shift_n = context.read_gpr(m) & 0xff; + const u32 result = Shift_C(context.read_gpr(n), SRType_ROR, shift_n, context.APSR.C, carry); + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } @@ -4212,11 +4422,31 @@ void ARMv7_instrs::TEQ_RSR(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::TST_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool carry = context.APSR.C; + u32 cond, n, imm32; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + n = (code.data & 0xf0000) >> 16; + imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); + + reject(n == 13 || n == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + const u32 result = context.read_gpr(n) & imm32; + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } } void ARMv7_instrs::TST_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h index 2a18646d42..01521ce9d5 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h @@ -79,6 +79,10 @@ namespace ARMv7_instrs void CMP_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void CMP_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void DBG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void DMB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void DSB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void EOR_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void EOR_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void EOR_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index cf3725a3f9..3e5b21c44e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -24,12 +24,63 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g case '%': { const auto start = fmt - 1; - const bool number_sign = *fmt == '#' ? fmt++, true : false; - switch (*fmt++) + // read flags + const bool plus_sign = *fmt == '+' ? fmt++, true : false; + const bool minus_sign = *fmt == '-' ? fmt++, true : false; + const bool space_sign = *fmt == ' ' ? fmt++, true : false; + const bool number_sign = *fmt == '#' ? fmt++, true : false; + const bool zero_padding = *fmt == '0' ? fmt++, true : false; + + // read width + const u32 width = [&]() -> u32 + { + u32 width = 0; + + if (*fmt == '*') + { + fmt++; + return context.get_next_gpr_arg(g_count, f_count, v_count); + } + + while (*fmt - '0' < 10) + { + width = width * 10 + (*fmt++ - '0'); + } + + return width; + }(); + + // read precision + const u32 prec = [&]() -> u32 + { + u32 prec = 0; + + if (*fmt != '.') + { + return 0; + } + + if (*++fmt == '*') + { + fmt++; + return context.get_next_gpr_arg(g_count, f_count, v_count); + } + + while (*fmt - '0' < 10) + { + prec = prec * 10 + (*fmt++ - '0'); + } + + return prec; + }(); + + switch (char cf = *fmt++) { case '%': { + if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; + result += '%'; continue; } @@ -39,20 +90,38 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g // signed decimal const s64 value = context.get_next_gpr_arg(g_count, f_count, v_count); + if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; + result += fmt::to_sdec(value); continue; } case 'x': + case 'X': { // hexadecimal const u64 value = context.get_next_gpr_arg(g_count, f_count, v_count); + if (plus_sign || minus_sign || space_sign || prec) break; + if (number_sign && value) { - result += "0x"; + result += cf == 'x' ? "0x" : "0X"; } - result += fmt::to_hex(value); + const std::string& hex = cf == 'x' ? fmt::to_hex(value) : fmt::toupper(fmt::to_hex(value)); + + if (hex.length() >= width) + { + result += hex; + } + else if (zero_padding) + { + result += std::string(width - hex.length(), '0') + hex; + } + else + { + result += hex + std::string(width - hex.length(), ' '); + } continue; } case 's': @@ -60,14 +129,14 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g // string auto string = vm::psv::ptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); + if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; + result += string.get_ptr(); continue; } - default: - { - throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); - } } + + throw fmt::format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); } } @@ -127,21 +196,21 @@ namespace sce_libc_func void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... { sceLibc.Warning("printf(fmt=0x%x)", fmt); + sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); - sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr()); + const std::string& result = armv7_fmt(context, fmt, 1, 0, 0); + sceLibc.Log("*** -> '%s'", result); - LOG_NOTICE(TTY, armv7_fmt(context, fmt, 1, 0, 0)); + LOG_NOTICE(TTY, result); } void sprintf(ARMv7Context& context, vm::psv::ptr str, vm::psv::ptr fmt) // va_args... { sceLibc.Warning("sprintf(str=0x%x, fmt=0x%x)", str, fmt); - - sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr()); + sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, 2, 0, 0); - - sceLibc.Notice("*** res -> '%s'", result); + sceLibc.Log("*** -> '%s'", result); ::memcpy(str.get_ptr(), result.c_str(), result.size() + 1); }