Skip to content

Commit f1dc157

Browse files
committed
Merge remote-tracking branch 'origin/GP-2245_ghidorahrex_powerpc_mtsmsr_fix--SQUASHED' into patch
2 parents af042aa + 32eadb2 commit f1dc157

File tree

2 files changed

+39
-30
lines changed

2 files changed

+39
-30
lines changed

Ghidra/Processors/PowerPC/data/languages/ppc_embedded.sinc

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,36 +113,33 @@
113113
DCRN = D;
114114
}
115115

116+
# mtmsr varies from processor to processor. This version is consistent with PowerISA v2.07B
116117
#mtmsr r0,0 0x7c 00 01 24
117118
:mtmsr S,0 is OP=31 & S & BITS_17_20=0 & MSR_L=0 & BITS_11_15=0 & XOP_1_10=146 & BIT_0=0
118119
{
119-
bit58:$(REGISTER_SIZE) = (S >> 5) & 1; #bit 58
120-
bit49:$(REGISTER_SIZE) = (S >> 14)& 1; #bit 49
121-
bit59:$(REGISTER_SIZE) = (S >> 4) & 1; #bit 59
122-
@ifdef BIT_64
123-
tmp:8 = S & 0x00000000ffff6fcf; #0b00000000000000000000000000000000 1111 1111 1111 1111 0110 1111 1100 1111
124-
tmp = tmp & ((bit58 | bit49) << 5);
125-
tmp = tmp & ((bit59 | bit49) << 4);
126-
MSR = MSR & 0xffffffff00009030 | tmp;
127-
@else
128-
tmp:4 = S & 0xffff6fcf;
129-
tmp = tmp & ((bit58 | bit49) << 5);
130-
tmp = tmp & ((bit59 | bit49) << 4);
131-
MSR = MSR & 0x00009000 | tmp;
132-
@endif
120+
121+
bit59:$(REGISTER_SIZE) = (S >> 4) & 1; #bit 59
122+
bit58:$(REGISTER_SIZE) = (S >> 5) & 1; #bit 58
123+
bit49:$(REGISTER_SIZE) = (S >> 14) & 1; #bit 49
124+
bit48:$(REGISTER_SIZE) = (S >> 15) & 1; #bit 48
125+
126+
local mask:$(REGISTER_SIZE) = 0xffff6fcf; # preserves bits 32:47 49:50 52:57 60:62
127+
local tmp:$(REGISTER_SIZE) = S & mask; # 1111 1111 1111 1111 0110 1111 1100 1111
128+
129+
tmp = tmp | ((bit48 | bit49) << 15); # MSR 48 <- (RS) 48 | (RS) 49
130+
tmp = tmp | ((bit58 | bit49) << 5); # MSR 58 <- (RS) 58 | (RS) 49
131+
tmp = tmp | ((bit59 | bit49) << 4); # MSR 59 <- (RS) 59 | (RS) 49
132+
MSR = (MSR & ~mask) | tmp;
133133
}
134134

135135
#mtmsr r0,1 0x7c 01 01 24
136136
:mtmsr S,1 is OP=31 & S & BITS_17_20=0 & MSR_L=1 & BITS_11_15=0 & XOP_1_10=146 & BIT_0=0
137137
{
138-
@ifdef BIT_64
139-
mask:8 = 0x000000000000fffe;
140-
@else
141-
mask:4 = 0x0000fffe;
142-
@endif
138+
mask:$(REGISTER_SIZE) = 0x8002; #preserves bits 48 and 62
143139
MSR = (MSR & ~mask) | (S & mask);
144140
}
145141

142+
146143
#mtspr spr000,r0 0x7c 00 02 a6
147144
:mtspr SPRVAL,S is OP=31 & SPRVAL & S & XOP_1_10=467 & BIT_0=0
148145
{

Ghidra/Processors/PowerPC/data/languages/ppc_instructions.sinc

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,29 +3151,41 @@ define pcodeop lswxOp;
31513151
cr1flags();
31523152
}
31533153

3154-
# This instruction is not exclusive to 64 bit processors, per page 1259 of the PowerISA manual.
3155-
# However, it does seem to require 64 bit registers, so it is currently restricted to 64 bit machines.
3154+
# This instruction is not exclusive to 64 bit processors, per page 1405 of the PowerISA manual.
3155+
# Prior to the Power ISA introduction, PowerPC architecture had 32-bit versions of the MSR in 32-bit implementations.
3156+
# Since this instruction requires 64-bit processsors, it is currently restricted to 64 bit machines.
3157+
# mtmsrd varies from processor to processor. This version is consistent with PowerISA v2.07B
31563158
@ifdef BIT_64
31573159
#mtmsrd r0,0 0x7c 00 01 64
31583160
:mtmsrd S,0 is $(NOTVLE) & OP=31 & S & BITS_17_20=0 & MSR_L=0 & BITS_11_15=0 & XOP_1_10=178 & BIT_0=0
31593161
{
3160-
bit0:8 = S >> 63 & 1;
3161-
bit1:8 = S >> 62 & 1;
3162-
bit49:8 = (S >> 14)& 1;
3163-
bit59:8 = (S >> 4) & 1;
3164-
tmp:8 = S & 0x6fffffffffff6fcf;
3165-
tmp = tmp & ((bit0 | bit1) << 63);
3166-
tmp = tmp & ((bit59 | bit49) << 5);
3167-
MSR = MSR & 0xefffffff00009020 | tmp;
3162+
local bit59:$(REGISTER_SIZE) = (S >> 4) & 1; #bit 59
3163+
local bit58:$(REGISTER_SIZE) = (S >> 5) & 1; #bit 58
3164+
local bit49:$(REGISTER_SIZE) = (S >> 14) & 1; #bit 49
3165+
local bit48:$(REGISTER_SIZE) = (S >> 15) & 1; #bit 48
3166+
3167+
local bits2931:$(REGISTER_SIZE) = zext(S[32,3]); #bits 29-31
3168+
local mbits2931:$(REGISTER_SIZE) = zext(MSR[32,3]); #bits 29-31
3169+
local cond = (mbits2931 != 0x2)|(bits2931 != 0);
3170+
bits2931 = (zext(cond) * bits2931) + (zext(!cond) * mbits2931);
3171+
local mask:$(REGISTER_SIZE) =0xeffffff8ffff6fce;
3172+
tmp:8 = S & mask; #preserves (RS) 0:2 4:40 42:47 49:50 52:57 60:62
3173+
3174+
tmp = tmp | (bits2931) << 32;
3175+
tmp = tmp | ((bit48 | bit49) << 15); # MSR 48 <- (RS) 48 | (RS) 49
3176+
tmp = tmp | ((bit58 | bit49) << 5); # MSR 58 <- (RS) 58 | (RS) 49
3177+
tmp = tmp | ((bit59 | bit49) << 4); # MSR 59 <- (RS) 59 | (RS) 49
3178+
MSR = (MSR & ~mask) | tmp;
31683179
}
31693180

31703181
#mtmsrd r0,1 0x7c 01 01 64
31713182
:mtmsrd S,1 is $(NOTVLE) & OP=31 & S & BITS_17_20=0 & MSR_L=1 & BITS_11_15=0 & XOP_1_10=178 & BIT_0=0
31723183
{
3173-
mask:8 = 0x000000000000fffe & S;
3184+
mask:$(REGISTER_SIZE) = 0x8002;
31743185
MSR = (MSR & ~mask) | (S & mask);
31753186
}
31763187
@endif
3188+
31773189
CRM_val: crmval is CRM [crmval = CRM+0;] {export *[const]:1 crmval;}
31783190
#mtocrf 10,r0 0x7c 21 01 20
31793191
:mtocrf CRM_val,S is OP=31 & S & BIT_20=1 & CRM_val & CRM0 & CRM1 & CRM2 & CRM3 & CRM4 & CRM5 & CRM6 & CRM7 & BIT_11=0 & XOP_1_10=144 & BIT_0=0

0 commit comments

Comments
 (0)