aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/ppc64
diff options
context:
space:
mode:
authorPaul E. Murphy <murp@ibm.com>2021-10-21 15:25:14 -0500
committerPaul Murphy <murp@ibm.com>2022-05-06 17:56:02 +0000
commit4a5711c3cf944b3ff51af261166ef34b2ed22b8a (patch)
tree37737fd61ccf588e0b164cd3a985e065983279a8 /src/cmd/internal/obj/ppc64
parent091e913414794d9176861b1ffcdbcfdc2d742af3 (diff)
downloadgo-4a5711c3cf944b3ff51af261166ef34b2ed22b8a.tar.xz
cmd/compile,cmd/asm: fix ppc64 usage of BI argument of BC opcode
Avoid coercing the CR bit into a GPR register type argument, and move the existing usage to CRx_y register types. And, update the compiler usage to this. This transformation is done internally, so it should not alter existing assembly code. Likewise, add assembly tests for all optab entries of BC/BR. This found some cases which were not possible to realize with handwritten asm, or assemble to something very unexpected if generated by the compiler. The following optab entries are removed, and the cases simplified or removed: {as: ABR, a3: C_SCON, a6: C_LR, type_: 18, size: 4} This existed only to pass the BH hint to JMP (LR) from compiler generated code. It cannot be matched with asm. Instead, add and support 4-operand form "BC{,L} $BO, $BI, $BH, (LR)". {as: ABR, a1: C_REG, a6: C_CTR, type_: 18, size: 4} Could be used like "BR R1, (CTR)", but always compiles to bctr irrespective of arg 1. Any usage should be rewritten as "JMP (CTR)", or rewritten if this was not the intended behavior. {as: ABR, a6: C_ZOREG, type_: 15, size: 8}: {as: ABC, a6: C_ZOREG, type_: 15, size: 8}, Not reachable: 0(reg) is coerced to reg in assembler frontend. {as: ABC, a2: C_REG, a6: C_LR, type_: 18, size: 4} {as: ABC, a2: C_REG, a6: C_CTR, type_: 18, size: 4} Only usable from the compiler. However, the compiler does not generate this form today. Without a BO operand (usually in a1), it is not clear what this should assemble to. Change-Id: I1b5151f884a5877e4a610e6fd41261e8e64c5454 Reviewed-on: https://go-review.googlesource.com/c/go/+/357775 Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Run-TryBot: Paul Murphy <murp@ibm.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/internal/obj/ppc64')
-rw-r--r--src/cmd/internal/obj/ppc64/a.out.go3
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go39
-rw-r--r--src/cmd/internal/obj/ppc64/asm_test.go21
-rw-r--r--src/cmd/internal/obj/ppc64/list9.go6
4 files changed, 29 insertions, 40 deletions
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go
index 25081efcee..30eba4339a 100644
--- a/src/cmd/internal/obj/ppc64/a.out.go
+++ b/src/cmd/internal/obj/ppc64/a.out.go
@@ -264,6 +264,8 @@ const (
REG_SPECIAL = REG_CR0
+ REG_CRBIT0 = REG_CR0LT // An alias for a Condition Register bit 0
+
REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers
REG_XER = REG_SPR0 + 1
@@ -368,6 +370,7 @@ const (
// Common values for the BO field.
const (
+ BO_ALWAYS = 20 // branch unconditionally
BO_BCTR = 16 // decrement ctr, branch on ctr != 0
BO_NOTBCTR = 18 // decrement ctr, branch on ctr == 0
BO_BCR = 12 // branch on cr value
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index 399e17ebab..aa2737d8f0 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -291,20 +291,15 @@ var optab = []Optab{
{as: ASYSCALL, a1: C_SCON, type_: 77, size: 12},
{as: ABEQ, a6: C_SBRA, type_: 16, size: 4},
{as: ABEQ, a1: C_CREG, a6: C_SBRA, type_: 16, size: 4},
- {as: ABR, a6: C_LBRA, type_: 11, size: 4},
- {as: ABR, a6: C_LBRAPIC, type_: 11, size: 8},
- {as: ABC, a1: C_SCON, a2: C_REG, a6: C_SBRA, type_: 16, size: 4},
- {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA, type_: 17, size: 4},
- {as: ABR, a6: C_LR, type_: 18, size: 4},
- {as: ABR, a3: C_SCON, a6: C_LR, type_: 18, size: 4},
- {as: ABR, a6: C_CTR, type_: 18, size: 4},
- {as: ABR, a1: C_REG, a6: C_CTR, type_: 18, size: 4},
- {as: ABR, a6: C_ZOREG, type_: 15, size: 8},
- {as: ABC, a2: C_REG, a6: C_LR, type_: 18, size: 4},
- {as: ABC, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
- {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LR, type_: 18, size: 4},
- {as: ABC, a1: C_SCON, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
- {as: ABC, a6: C_ZOREG, type_: 15, size: 8},
+ {as: ABR, a6: C_LBRA, type_: 11, size: 4}, // b label
+ {as: ABR, a6: C_LBRAPIC, type_: 11, size: 8}, // b label; nop
+ {as: ABR, a6: C_LR, type_: 18, size: 4}, // blr
+ {as: ABR, a6: C_CTR, type_: 18, size: 4}, // bctr
+ {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_SBRA, type_: 16, size: 4}, // bc bo, bi, label
+ {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_LBRA, type_: 17, size: 4}, // bc bo, bi, label
+ {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_LR, type_: 18, size: 4}, // bclr bo, bi
+ {as: ABC, a1: C_SCON, a2: C_CRBIT, a3: C_SCON, a6: C_LR, type_: 18, size: 4}, // bclr bo, bi, bh
+ {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_CTR, type_: 18, size: 4}, // bcctr bo, bi
{as: ABDNZ, a6: C_SBRA, type_: 16, size: 4},
{as: ASYNC, type_: 46, size: 4},
{as: AWORD, a1: C_LCON, type_: 40, size: 4},
@@ -708,7 +703,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q.Link = p.Link
p.To.SetTarget(p.Link)
p.Link = q
- p.Reg = bi // TODO: This is a hack since BI bits are not enumerated as registers
+ p.Reg = REG_CRBIT0 + bi
} else {
// Rewrite
// BC ...,far_away_target
@@ -2808,20 +2803,6 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
}
o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
- case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
- var v int32
- if p.As == ABC || p.As == ABCL {
- v = c.regoff(&p.To) & 31
- } else {
- v = 20 /* unconditional */
- }
- o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
- o2 = OPVCC(19, 16, 0, 0)
- if p.As == ABL || p.As == ABCL {
- o2 |= 1
- }
- o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
-
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
var v int32
var bh uint32 = 0
diff --git a/src/cmd/internal/obj/ppc64/asm_test.go b/src/cmd/internal/obj/ppc64/asm_test.go
index 1de6e76b09..c16d4a6e73 100644
--- a/src/cmd/internal/obj/ppc64/asm_test.go
+++ b/src/cmd/internal/obj/ppc64/asm_test.go
@@ -232,46 +232,45 @@ func TestLarge(t *testing.T) {
// Test the interesting cases of conditional branch rewrites for too-far targets. Simple conditional
// branches can be made to reach with one JMP insertion, compound conditionals require two.
//
- // TODO: BI is interpreted as a register (the R???x/R0 should be $x)
// beq <-> bne conversion (insert one jump)
{"BEQ",
[]string{``,
- `0x20030 131120\s\(.*\)\tBC\t\$4,\sR\?\?\?2,\s131128`,
+ `0x20030 131120\s\(.*\)\tBC\t\$4,\sCR0EQ,\s131128`,
`0x20034 131124\s\(.*\)\tJMP\t0`},
[]string{``,
- `0x0000 00000\s\(.*\)\tBC\t\$4,\sR\?\?\?2,\s8`,
+ `0x0000 00000\s\(.*\)\tBC\t\$4,\sCR0EQ,\s8`,
`0x0004 00004\s\(.*\)\tJMP\t131128`},
},
{"BNE",
[]string{``,
- `0x20030 131120\s\(.*\)\tBC\t\$12,\sR\?\?\?2,\s131128`,
+ `0x20030 131120\s\(.*\)\tBC\t\$12,\sCR0EQ,\s131128`,
`0x20034 131124\s\(.*\)\tJMP\t0`},
[]string{``,
- `0x0000 00000\s\(.*\)\tBC\t\$12,\sR\?\?\?2,\s8`,
+ `0x0000 00000\s\(.*\)\tBC\t\$12,\sCR0EQ,\s8`,
`0x0004 00004\s\(.*\)\tJMP\t131128`}},
// bdnz (BC 16,0,tgt) <-> bdz (BC 18,0,+4) conversion (insert one jump)
{"BC 16,0,",
[]string{``,
- `0x20030 131120\s\(.*\)\tBC\t\$18,\s131128`,
+ `0x20030 131120\s\(.*\)\tBC\t\$18,\sCR0LT,\s131128`,
`0x20034 131124\s\(.*\)\tJMP\t0`},
[]string{``,
- `0x0000 00000\s\(.*\)\tBC\t\$18,\s8`,
+ `0x0000 00000\s\(.*\)\tBC\t\$18,\sCR0LT,\s8`,
`0x0004 00004\s\(.*\)\tJMP\t131128`}},
{"BC 18,0,",
[]string{``,
- `0x20030 131120\s\(.*\)\tBC\t\$16,\s131128`,
+ `0x20030 131120\s\(.*\)\tBC\t\$16,\sCR0LT,\s131128`,
`0x20034 131124\s\(.*\)\tJMP\t0`},
[]string{``,
- `0x0000 00000\s\(.*\)\tBC\t\$16,\s8`,
+ `0x0000 00000\s\(.*\)\tBC\t\$16,\sCR0LT,\s8`,
`0x0004 00004\s\(.*\)\tJMP\t131128`}},
// bdnzt (BC 8,0,tgt) <-> bdnzt (BC 8,0,+4) conversion (insert two jumps)
{"BC 8,0,",
[]string{``,
- `0x20034 131124\s\(.*\)\tBC\t\$8,\sR0,\s131132`,
+ `0x20034 131124\s\(.*\)\tBC\t\$8,\sCR0LT,\s131132`,
`0x20038 131128\s\(.*\)\tJMP\t131136`,
`0x2003c 131132\s\(.*\)\tJMP\t0\n`},
[]string{``,
- `0x0000 00000\s\(.*\)\tBC\t\$8,\sR0,\s8`,
+ `0x0000 00000\s\(.*\)\tBC\t\$8,\sCR0LT,\s8`,
`0x0004 00004\s\(.*\)\tJMP\t12`,
`0x0008 00008\s\(.*\)\tJMP\t131136\n`}},
}
diff --git a/src/cmd/internal/obj/ppc64/list9.go b/src/cmd/internal/obj/ppc64/list9.go
index ea0dae9e02..dda8d5abd0 100644
--- a/src/cmd/internal/obj/ppc64/list9.go
+++ b/src/cmd/internal/obj/ppc64/list9.go
@@ -104,3 +104,9 @@ func DRconv(a int) string {
fp += s
return fp
}
+
+func ConstantToCRbit(c int64) (int16, bool) {
+ reg64 := REG_CRBIT0 + c
+ success := reg64 >= REG_CR0LT && reg64 <= REG_CR7SO
+ return int16(reg64), success
+}