1
0
mirror of https://github.com/golang/go synced 2024-11-19 17:44:43 -07:00

cmd/asm, cmd/internal/obj/ppc64: add Immediate Shifted opcodes for ppc64x

This change adds ADD/AND/OR/XOR Immediate Shifted instructions for
ppc64x so they are usable in Go asm code. These instructions were
originally present in asm9.go, but they were only usable in that
file (as -AADD, -AANDCC, -AOR, -AXOR). These old mnemonics are now
removed.

Updates #23845

Change-Id: Ifa2fac685e8bc628cb241dd446adfc3068181826
Reviewed-on: https://go-review.googlesource.com/94115
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
Carlos Eduardo Seo 2018-01-03 17:55:40 -02:00 committed by Lynn Boger
parent d50bb8dbb9
commit 9a9a8c0165
4 changed files with 64 additions and 15 deletions

View File

@ -1123,6 +1123,24 @@ label1:
// addex RT, RA, RB, CY // addex RT, RA, RB, CY
ADDEX R1, R2, $0, R3 ADDEX R1, R2, $0, R3
// Immediate-shifted operations
// ADDIS SI, RA, RT produces
// addis RT, RA, SI
ADDIS $8, R3, R4
ADDIS $-1, R3, R4
// ANDISCC UI, RS, RA produces
// andis. RA, RS, UI
ANDISCC $7, R4, R5
// ORIS UI, RS, RA produces
// oris RA, RS, UI
ORIS $4, R2, R3
// XORIS UI, RS, RA produces
// xoris RA, RS, UI
XORIS $1, R1, R2
// //
// NOP // NOP
// //

View File

@ -378,6 +378,7 @@ const (
const ( const (
AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota
AADDCC AADDCC
AADDIS
AADDV AADDV
AADDVCC AADDVCC
AADDC AADDC
@ -401,6 +402,7 @@ const (
AANDCC AANDCC
AANDN AANDN
AANDNCC AANDNCC
AANDISCC
ABC ABC
ABCL ABCL
ABEQ ABEQ
@ -536,6 +538,7 @@ const (
AORCC AORCC
AORN AORN
AORNCC AORNCC
AORIS
AREM AREM
AREMCC AREMCC
AREMV AREMV
@ -581,6 +584,7 @@ const (
ASYNC ASYNC
AXOR AXOR
AXORCC AXORCC
AXORIS
ADCBF ADCBF
ADCBI ADCBI

View File

@ -8,6 +8,7 @@ import "cmd/internal/obj"
var Anames = []string{ var Anames = []string{
obj.A_ARCHSPECIFIC: "ADD", obj.A_ARCHSPECIFIC: "ADD",
"ADDCC", "ADDCC",
"ADDIS",
"ADDV", "ADDV",
"ADDVCC", "ADDVCC",
"ADDC", "ADDC",
@ -31,6 +32,7 @@ var Anames = []string{
"ANDCC", "ANDCC",
"ANDN", "ANDN",
"ANDNCC", "ANDNCC",
"ANDISCC",
"BC", "BC",
"BCL", "BCL",
"BEQ", "BEQ",
@ -166,6 +168,7 @@ var Anames = []string{
"ORCC", "ORCC",
"ORN", "ORN",
"ORNCC", "ORNCC",
"ORIS",
"REM", "REM",
"REMCC", "REMCC",
"REMV", "REMV",
@ -211,6 +214,7 @@ var Anames = []string{
"SYNC", "SYNC",
"XOR", "XOR",
"XORCC", "XORCC",
"XORIS",
"DCBF", "DCBF",
"DCBI", "DCBI",
"DCBST", "DCBST",

View File

@ -88,6 +88,8 @@ var optab = []Optab{
{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0}, {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0}, {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
{AADDIS, C_ADDCON, C_REG, C_NONE, C_REG, 20, 4, 0},
{AADDIS, C_ADDCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
@ -104,6 +106,8 @@ var optab = []Optab{
{AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
{AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
{AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
{AANDISCC, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
{AANDISCC, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
{AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
{AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
@ -124,6 +128,8 @@ var optab = []Optab{
{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
{AORIS, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
{AORIS, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */ {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
@ -1522,7 +1528,6 @@ func buildop(ctxt *obj.Link) {
case AAND: /* logical op Rb,Rs,Ra; no literal */ case AAND: /* logical op Rb,Rs,Ra; no literal */
opset(AANDN, r0) opset(AANDN, r0)
opset(AANDNCC, r0) opset(AANDNCC, r0)
opset(AEQV, r0) opset(AEQV, r0)
opset(AEQVCC, r0) opset(AEQVCC, r0)
@ -1677,9 +1682,12 @@ func buildop(ctxt *obj.Link) {
opset(ANEGV, r0) opset(ANEGV, r0)
opset(ANEGVCC, r0) opset(ANEGVCC, r0)
case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
opset(AXOR, r0) opset(AXOR, r0)
case AORIS: /* oris/xoris $uimm,Rs,Ra */
opset(AXORIS, r0)
case ASLW: case ASLW:
opset(ASLWCC, r0) opset(ASLWCC, r0)
opset(ASRW, r0) opset(ASRW, r0)
@ -1792,7 +1800,9 @@ func buildop(ctxt *obj.Link) {
opset(AFTSQRT, r0) opset(AFTSQRT, r0)
case AADD, case AADD,
AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ AADDIS,
AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
AANDISCC,
AFMOVSX, AFMOVSX,
AFMOVSZ, AFMOVSZ,
ALSW, ALSW,
@ -2624,7 +2634,7 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
//if(dlm) reloc(&p->from, p->pc, 0); //if(dlm) reloc(&p->from, p->pc, 0);
case 20: /* add $ucon,,r */ case 20: /* add $ucon,,r | addis $addcon,r,r */
v := c.regoff(&p.From) v := c.regoff(&p.From)
r := int(p.Reg) r := int(p.Reg)
@ -2634,7 +2644,11 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) { if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
c.ctxt.Diag("literal operation on R0\n%v", p) c.ctxt.Diag("literal operation on R0\n%v", p)
} }
o1 = AOP_IRR(c.opirr(-p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) if p.As == AADDIS {
o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
} else {
o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
}
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */ case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
if p.To.Reg == REGTMP || p.Reg == REGTMP { if p.To.Reg == REGTMP || p.Reg == REGTMP {
@ -3063,14 +3077,23 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v)) o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
case 59: /* or/and $ucon,,r */ case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
v := c.regoff(&p.From) v := c.regoff(&p.From)
r := int(p.Reg) r := int(p.Reg)
if r == 0 { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = LOP_IRR(c.opirr(-p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ switch p.As {
case AOR:
o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
case AXOR:
o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
case AANDCC:
o1 = LOP_IRR(c.opirr(AANDCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
default:
o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
}
case 60: /* tw to,a,b */ case 60: /* tw to,a,b */
r := int(c.regoff(&p.From) & 31) r := int(c.regoff(&p.From) & 31)
@ -4442,13 +4465,13 @@ func (c *ctxt9) opirr(a obj.As) uint32 {
return OPVCC(12, 0, 0, 0) return OPVCC(12, 0, 0, 0)
case AADDCCC: case AADDCCC:
return OPVCC(13, 0, 0, 0) return OPVCC(13, 0, 0, 0)
case -AADD: case AADDIS:
return OPVCC(15, 0, 0, 0) /* ADDIS/CAU */ return OPVCC(15, 0, 0, 0) /* ADDIS */
case AANDCC: case AANDCC:
return OPVCC(28, 0, 0, 0) return OPVCC(28, 0, 0, 0)
case -AANDCC: case AANDISCC:
return OPVCC(29, 0, 0, 0) /* ANDIS./ANDIU. */ return OPVCC(29, 0, 0, 0) /* ANDIS. */
case ABR: case ABR:
return OPVCC(18, 0, 0, 0) return OPVCC(18, 0, 0, 0)
@ -4506,8 +4529,8 @@ func (c *ctxt9) opirr(a obj.As) uint32 {
case AOR: case AOR:
return OPVCC(24, 0, 0, 0) return OPVCC(24, 0, 0, 0)
case -AOR: case AORIS:
return OPVCC(25, 0, 0, 0) /* ORIS/ORIU */ return OPVCC(25, 0, 0, 0) /* ORIS */
case ARLWMI: case ARLWMI:
return OPVCC(20, 0, 0, 0) /* rlwimi */ return OPVCC(20, 0, 0, 0) /* rlwimi */
@ -4584,8 +4607,8 @@ func (c *ctxt9) opirr(a obj.As) uint32 {
case AXOR: case AXOR:
return OPVCC(26, 0, 0, 0) /* XORIL */ return OPVCC(26, 0, 0, 0) /* XORIL */
case -AXOR: case AXORIS:
return OPVCC(27, 0, 0, 0) /* XORIU */ return OPVCC(27, 0, 0, 0) /* XORIS */
} }
c.ctxt.Diag("bad opcode i/r or i/r/r %v", a) c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)