From d5967f783476ec554f4e722550a37cc8de9eead5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 1 Apr 2022 20:37:36 -0400 Subject: [PATCH] Correct decoding of stwcx. and stdcx. --- InstructionSets/PowerPC/Decoder.cpp | 8 ++-- InstructionSets/PowerPC/Instruction.hpp | 41 +++++++++++++++++-- .../DingusdevPowerPCTests.mm | 13 +++++- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/InstructionSets/PowerPC/Decoder.cpp b/InstructionSets/PowerPC/Decoder.cpp index ea08b910c..86db71b4e 100644 --- a/InstructionSets/PowerPC/Decoder.cpp +++ b/InstructionSets/PowerPC/Decoder.cpp @@ -317,15 +317,15 @@ Instruction Decoder::decode(uint32_t opcode) { } // stwcx. and stdcx. - switch(opcode & 0b111111'00'00000000'000'111111111'1){ - case 0b011111'00'00000000'00000'0010010110'1: return Instruction(Operation::stwcx_, opcode); - case 0b011111'00'00000000'00000'0011010110'1: + switch(opcode & 0b111111'0000'0000'0000'0000'111111111'1) { + case 0b011111'0000'0000'0000'0000'010010110'1: return Instruction(Operation::stwcx_, opcode); + case 0b011111'0000'0000'0000'0000'011010110'1: if(is64bit(model_)) return Instruction(Operation::stdcx_, opcode); return Instruction(opcode); } // std and stdu - switch(opcode & 0b111111'00'00000000'00000000'000000'11){ + switch(opcode & 0b111111'00'00000000'00000000'000000'11) { case 0b111110'00'00000000'00000000'000000'00: return Instruction(Operation::std, opcode); case 0b111110'00'00000000'00000000'000000'01: if(is64bit(model_)) return Instruction(Operation::stdu, opcode); diff --git a/InstructionSets/PowerPC/Instruction.hpp b/InstructionSets/PowerPC/Instruction.hpp index 72a3042eb..90e5e2d8e 100644 --- a/InstructionSets/PowerPC/Instruction.hpp +++ b/InstructionSets/PowerPC/Instruction.hpp @@ -490,7 +490,17 @@ enum class Operation: uint8_t { /// frS(), rA(), rB() stfdx, - stfs, stfsu, stfsux, stfsx, sth, sthbrx, sthu, + /// Store floating point single precision. + /// stfs + /// frS() d() [ rA() ] + stfs, + + /// Store floating point single precision with update. + /// stfs + /// frS() d() [ rA() ] + stfsu, + + stfsux, stfsx, sth, sthbrx, sthu, /// Store half-word with update indexed. sthux, @@ -498,12 +508,31 @@ enum class Operation: uint8_t { /// Store half-word indexed. sthx, - stmw, stswi, stswx, stw, stwbrx, stwcx_, stwu, + stmw, stswi, stswx, stw, + + /// Store word byte-reverse indexed. + /// stwbrx + /// rS(), rA(), rB() + stwbrx, + + /// Store word conditional. + /// stwcx. + /// rS(), rA(), rB() + stwcx_, + + /// Store word with update. + /// stwu + /// rS(), d() [ rA() ] + stwu, /// Store word with update indexed. + /// stwux + /// rS(), rA(), rB() stwux, /// Store word indexed. + /// stwx + /// rS(), rA(), rB() stwx, subfx, @@ -511,6 +540,7 @@ enum class Operation: uint8_t { /// Subtract from carrying. /// subfc subfc. subfco subfco. subfcx, + subfex, /// Subtract from immediate carrying @@ -535,7 +565,12 @@ enum class Operation: uint8_t { // // MARK: - Optional. // - fresx, frsqrtex, fselx, fsqrtx, slbia, slbie, stfiwx, + fresx, frsqrtex, fselx, fsqrtx, slbia, slbie, + + /// Store floating point as integer word indexed. + /// stfiwx + /// frS(), rA(), rB() + stfiwx, // // MARK: - 64-bit only PowerPC instructions. diff --git a/OSBindings/Mac/Clock SignalTests/DingusdevPowerPCTests.mm b/OSBindings/Mac/Clock SignalTests/DingusdevPowerPCTests.mm index df770ae51..be44c5cd5 100644 --- a/OSBindings/Mac/Clock SignalTests/DingusdevPowerPCTests.mm +++ b/OSBindings/Mac/Clock SignalTests/DingusdevPowerPCTests.mm @@ -372,7 +372,6 @@ NSString *condition(uint32_t code) { ABCz(lhbrx); ABCz(lwbrx); ABCz(lwarx); - ABCz(stwcx_); ABCz(stwbrx); ABCz(sthbrx); @@ -428,6 +427,18 @@ NSString *condition(uint32_t code) { #undef ASB +#define SAB(x) \ + case Operation::x: \ + AssertEqualOperationName(operation, @#x, instruction); \ + AssertEqualR(columns[3], instruction.rS()); \ + AssertEqualR(columns[4], instruction.rA(), false); \ + AssertEqualR(columns[5], instruction.rB()); \ + break; + + SAB(stwcx_); + +#undef SAB + case Operation::bcx: case Operation::bclrx: case Operation::bcctrx: {