Skip to content

Commit 5e4c51d

Browse files
pmurlaboger
authored andcommitted
ppc64asm: fix plan9 style decoding issues
This reworks the decoding of CR bit fields to correctly decode the fcmp/cmp/setbc families of instructions. Comparison instructions always produce a result in a CR field, thus it should be listed last if not implied to be CR0. Furthermore, remove the context sensitive decoding of CR field and CR bit type arguments from plan9Arg. These edge cases are better handled during the per-instruction combining of decoded arguments. This allows setbc like instructions to decode correctly without special handling. Change-Id: I264a600034b5abb8901b0c2e6bffe2887200ac27 Reviewed-on: https://go-review.googlesource.com/c/arch/+/347569 Run-TryBot: Paul Murphy <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Carlos Eduardo Seo <[email protected]> Trust: Lynn Boger <[email protected]> Trust: Cherry Mui <[email protected]>
1 parent ebb09ed commit 5e4c51d

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed

ppc64/ppc64asm/plan9.go

+34-37
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
3030
break
3131
}
3232
if s := plan9Arg(&inst, i, pc, a, symname); s != "" {
33-
// In the case for some BC instructions, a CondReg arg has
34-
// both the CR and the branch condition encoded in its value.
35-
// plan9Arg will return a string with the string representation
36-
// of these values separated by a blank that will be treated
37-
// as 2 args from this point on.
38-
if strings.IndexByte(s, ' ') > 0 {
39-
t := strings.Split(s, " ")
40-
args = append(args, t[0])
41-
args = append(args, t[1])
42-
} else {
43-
args = append(args, s)
44-
}
33+
args = append(args, s)
4534
}
4635
}
4736
var op string
@@ -61,7 +50,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
6150
case 1:
6251
return fmt.Sprintf("%s %s", op, args[0])
6352
case 2:
64-
if inst.Op == COPY || inst.Op == PASTECC || inst.Op == FCMPO || inst.Op == FCMPU {
53+
if inst.Op == COPY || inst.Op == PASTECC {
6554
return op + " " + args[0] + "," + args[1]
6655
}
6756
return op + " " + args[1] + "," + args[0]
@@ -97,13 +86,13 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
9786
STQ, STFD, STFDU, STFS, STFSU:
9887
return op + " " + strings.Join(args, ",")
9988

100-
case CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:
101-
if len(args) == 2 {
102-
return op + " " + args[0] + "," + args[1]
103-
} else if len(args) == 3 {
104-
return op + " " + args[0] + "," + args[1] + "," + args[2]
89+
case FCMPU, FCMPO, CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:
90+
crf := int(inst.Args[0].(CondReg) - CR0)
91+
cmpstr := op + " " + args[1] + "," + args[2]
92+
if crf != 0 { // print CRx as the final operand if not implied (i.e BF != 0)
93+
cmpstr += "," + args[0]
10594
}
106-
return op + " " + args[0] + " ??"
95+
return cmpstr
10796

10897
case LIS:
10998
return "ADDIS $0," + args[1] + "," + args[0]
@@ -152,16 +141,15 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
152141
}
153142
return op + " " + strings.Join(args, ", ")
154143
case BC:
155-
if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set
156-
if len(args) == 4 {
157-
return fmt.Sprintf("B%s %s,%s", args[1], args[2], args[3])
158-
}
159-
return fmt.Sprintf("B%s %s", args[1], args[2])
160-
} else if int(inst.Args[0].(Imm))&0x1c == 4 && revCondMap[args[1]] != "" { // jump on cond bit not set
161-
if len(args) == 4 {
162-
return fmt.Sprintf("B%s %s,%s", revCondMap[args[1]], args[2], args[3])
144+
bo := int(inst.Args[0].(Imm))
145+
bi := int(inst.Args[1].(CondReg) - Cond0LT)
146+
bcname := condName[((bo&0x8)>>1)|(bi&0x3)]
147+
if bo&0x17 == 4 { // jump only a CR bit set/unset, no hints (at bits) set.
148+
if bi >= 4 {
149+
return fmt.Sprintf("B%s CR%d,%s", bcname, bi>>2, args[2])
150+
} else {
151+
return fmt.Sprintf("B%s %s", bcname, args[2])
163152
}
164-
return fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2])
165153
}
166154
return op + " " + strings.Join(args, ",")
167155
case BCCTR:
@@ -203,19 +191,14 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64)
203191
if inst.Op == ISEL {
204192
return fmt.Sprintf("$%d", (arg - Cond0LT))
205193
}
206-
if arg == CR0 && (strings.HasPrefix(inst.Op.String(), "cmp") || strings.HasPrefix(inst.Op.String(), "fcmp")) {
207-
return "" // don't show cr0 for cmp instructions
208-
} else if arg >= CR0 {
209-
return fmt.Sprintf("CR%d", int(arg-CR0))
210-
}
211194
bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4]
212-
if strings.HasPrefix(inst.Op.String(), "cr") {
213-
return fmt.Sprintf("CR%d%s", int(arg-Cond0LT)/4, bit)
214-
}
215195
if arg <= Cond0SO {
216196
return bit
197+
} else if arg > Cond0SO && arg <= Cond7SO {
198+
return fmt.Sprintf("CR%d%s", int(arg-Cond0LT)/4, bit)
199+
} else {
200+
return fmt.Sprintf("CR%d", int(arg-CR0))
217201
}
218-
return fmt.Sprintf("%s CR%d", bit, int(arg-Cond0LT)/4)
219202
case Imm:
220203
return fmt.Sprintf("$%d", arg)
221204
case SpReg:
@@ -281,6 +264,20 @@ var revCondMap = map[string]string{
281264
"LT": "GE", "GT": "LE", "EQ": "NE",
282265
}
283266

267+
// Lookup table to map BI[0:1] and BO[3] to an extended mnemonic for CR ops.
268+
// Bits 0-1 map to a bit with a CR field, and bit 2 selects the inverted (0)
269+
// or regular (1) extended mnemonic.
270+
var condName = []string{
271+
"GE",
272+
"LE",
273+
"NE",
274+
"NSO",
275+
"LT",
276+
"GT",
277+
"EQ",
278+
"SO",
279+
}
280+
284281
// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
285282
var plan9OpMap = map[Op]string{
286283
LWARX: "LWAR",

ppc64/ppc64asm/testdata/decode.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ e8610032| plan9 MOVW 48(R1),R3
4141
7c00422c| gnu dcbt r0,r8,0
4242
7c00422c| plan9 DCBT (R8)
4343
7fab3040| gnu cmpld cr7,r11,r6
44-
7fab3040| plan9 CMPU CR7,R11,R6
44+
7fab3040| plan9 CMPU R11,R6,CR7
4545
2c030001| gnu cmpwi r3,1
4646
2c030001| plan9 CMPW R3,$1
4747
7c2b4840| gnu cmpld r11,r9
@@ -855,3 +855,9 @@ f0400fe0| gnu xvcvsxddp vs2,vs1
855855
7c20003c| gnu wait 1,0
856856
4c000924| gnu rfebb 1
857857
0602000138800007| gnu pli r4,-8589869049
858+
7c5b03c0| plan9 SETNBCR CR6SO,R2
859+
fc811000| plan9 FCMPU F1,F2,CR1
860+
7c220176| plan9 BRD R1,R2
861+
7c2201b6| plan9 BRH R1,R2
862+
7c220136| plan9 BRW R1,R2
863+
7c2311b8| plan9 CFUGED R1,R2,R3

0 commit comments

Comments
 (0)