diff options
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/ppc64/a.out.go | 3 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/anames9.go | 1 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/asm9.go | 147 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/asm_test.go | 1 |
4 files changed, 93 insertions, 59 deletions
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go index 30eba4339a..6b6e498fd2 100644 --- a/src/cmd/internal/obj/ppc64/a.out.go +++ b/src/cmd/internal/obj/ppc64/a.out.go @@ -419,9 +419,10 @@ const ( C_SBRA /* A short offset argument to a branching instruction */ C_LBRA /* A long offset argument to a branching instruction */ C_LBRAPIC /* Like C_LBRA, but requires an extra NOP for potential TOC restore by the linker. */ - C_ZOREG /* An reg+reg memory arg, or a $0+reg memory op */ + C_ZOREG /* An $0+reg memory op */ C_SOREG /* An $n+reg memory arg where n is a 16 bit signed offset */ C_LOREG /* An $n+reg memory arg where n is a 32 bit signed offset */ + C_XOREG /* An reg+reg memory arg */ C_FPSCR /* The fpscr register */ C_XER /* The xer, holds the carry bit */ C_LR /* The link register */ diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go index 05bfd944d1..c6cc923b80 100644 --- a/src/cmd/internal/obj/ppc64/anames9.go +++ b/src/cmd/internal/obj/ppc64/anames9.go @@ -39,6 +39,7 @@ var cnames9 = []string{ "ZOREG", "SOREG", "LOREG", + "XOREG", "FPSCR", "XER", "LR", diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 94ad7a173b..ecd108e117 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -197,28 +197,36 @@ var optab = []Optab{ {as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4}, {as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, + {as: AMOVBU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 8, size: 8}, + {as: AMOVBU, a1: C_XOREG, a6: C_REG, type_: 109, size: 8}, {as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, + {as: AMOVBZU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4}, + {as: AMOVBZU, a1: C_XOREG, a6: C_REG, type_: 109, size: 4}, - {as: AMOVHBR, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4}, - {as: AMOVHBR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4}, + {as: AMOVHBR, a1: C_REG, a6: C_XOREG, type_: 44, size: 4}, + {as: AMOVHBR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, {as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 75, size: 12}, {as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 36, size: 12}, {as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 8, size: 8}, + {as: AMOVB, a1: C_XOREG, a6: C_REG, type_: 109, size: 8}, {as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, {as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, {as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, + {as: AMOVB, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4}, {as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8}, {as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, {as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4}, + {as: AMOVBZ, a1: C_XOREG, a6: C_REG, type_: 109, size: 4}, {as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, {as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, {as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, + {as: AMOVBZ, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4}, {as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4}, @@ -229,6 +237,7 @@ var optab = []Optab{ {as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8}, {as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8}, {as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4}, + {as: AMOVD, a1: C_XOREG, a6: C_REG, type_: 109, size: 4}, {as: AMOVD, a1: C_SOREG, a6: C_SPR, type_: 107, size: 8}, {as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, {as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8}, @@ -236,6 +245,7 @@ var optab = []Optab{ {as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4}, {as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, {as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, + {as: AMOVD, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVD, a1: C_SPR, a6: C_SOREG, type_: 106, size: 8}, {as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, {as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4}, @@ -251,28 +261,33 @@ var optab = []Optab{ {as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4}, {as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4}, {as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, + {as: AMOVW, a1: C_XOREG, a6: C_REG, type_: 109, size: 4}, {as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4}, {as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, {as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4}, {as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4}, {as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, + {as: AMOVW, a1: C_REG, a6: C_XOREG, type_: 108, size: 4}, {as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4}, {as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4}, {as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8}, {as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4}, + {as: AFMOVD, a1: C_XOREG, a6: C_FREG, type_: 109, size: 4}, {as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8}, {as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4}, {as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8}, {as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4}, {as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4}, + {as: AFMOVD, a1: C_FREG, a6: C_XOREG, type_: 108, size: 4}, {as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8}, {as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8}, - {as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4}, - {as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4}, + {as: AFMOVSX, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4}, + {as: AFMOVSX, a1: C_FREG, a6: C_XOREG, type_: 44, size: 4}, {as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4}, + {as: AFMOVSZ, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4}, {as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4}, {as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4}, @@ -325,7 +340,7 @@ var optab = []Optab{ {as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4}, /* floating test for sw square root, x-form */ {as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4}, /* copy/paste facility, x-form */ {as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4}, /* deliver random number, x-form */ - {as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */ + {as: ALDMX, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */ {as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */ {as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */ {as: ACRAND, a1: C_CRBIT, a2: C_CRBIT, a6: C_CRBIT, type_: 2, size: 4}, /* logical ops for condition register bits xl-form */ @@ -333,10 +348,10 @@ var optab = []Optab{ /* Vector instructions */ /* Vector load */ - {as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */ + {as: ALV, a1: C_XOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */ /* Vector store */ - {as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */ + {as: ASTV, a1: C_VREG, a6: C_XOREG, type_: 44, size: 4}, /* vector store, x-form */ /* Vector logical */ {as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */ @@ -405,26 +420,26 @@ var optab = []Optab{ {as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */ /* VSX vector load */ - {as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */ + {as: ALXVD2X, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */ {as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4}, /* vsx vector load, dq-form */ {as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */ /* VSX vector store */ - {as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */ + {as: ASTXVD2X, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */ {as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4}, /* vsx vector store, dq-form */ {as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */ /* VSX scalar load */ - {as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */ + {as: ALXSDX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */ /* VSX scalar store */ - {as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */ + {as: ASTXSDX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */ /* VSX scalar as integer load */ - {as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */ + {as: ALXSIWAX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */ /* VSX scalar store as integer */ - {as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */ + {as: ASTXSIWX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */ /* VSX move from VSR */ {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4}, @@ -488,24 +503,25 @@ var optab = []Optab{ {as: AFCMPO, a1: C_FREG, a2: C_CREG, a6: C_FREG, type_: 70, size: 4}, {as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4}, {as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4}, - {as: ADCBF, a1: C_ZOREG, type_: 43, size: 4}, {as: ADCBF, a1: C_SOREG, type_: 43, size: 4}, - {as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4}, + {as: ADCBF, a1: C_XOREG, type_: 43, size: 4}, + {as: ADCBF, a1: C_XOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4}, {as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4}, - {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4}, - {as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4}, - {as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4}, - {as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4}, - {as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4}, - {as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4}, + {as: ADCBF, a1: C_XOREG, a6: C_SCON, type_: 43, size: 4}, + {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_XOREG, type_: 44, size: 4}, + {as: AECIWX, a1: C_XOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4}, + {as: AECOWX, a1: C_REG, a6: C_XOREG, type_: 44, size: 4}, + {as: AECIWX, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, + {as: ALDAR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, + {as: ALDAR, a1: C_XOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4}, {as: AEIEIO, type_: 46, size: 4}, {as: ATLBIE, a1: C_REG, type_: 49, size: 4}, {as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4}, {as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4}, {as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4}, - {as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4}, + {as: ASTSW, a1: C_REG, a6: C_XOREG, type_: 44, size: 4}, {as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4}, - {as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4}, + {as: ALSW, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, {as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4}, {as: APNOP, type_: 105, size: 8, ispfx: true}, @@ -583,7 +599,7 @@ func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int { switch class { case C_SACON, C_LACON: return REGSP - case C_LOREG, C_SOREG, C_ZOREG: + case C_LOREG, C_SOREG, C_ZOREG, C_XOREG: switch a.Name { case obj.NAME_EXTERN, obj.NAME_STATIC: return REGSB @@ -881,6 +897,13 @@ func (c *ctxt9) aclass(a *obj.Addr) int { return c.aclassreg(a.Reg) case obj.TYPE_MEM: + if a.Index != 0 { + if a.Name != obj.NAME_NONE || a.Offset != 0 { + c.ctxt.Logf("Unexpected Instruction operand index %d offset %d class %d \n", a.Index, a.Offset, a.Class) + + } + return C_XOREG + } switch a.Name { case obj.NAME_GOTREF, obj.NAME_TOCREF: return C_ADDR @@ -903,6 +926,7 @@ func (c *ctxt9) aclass(a *obj.Addr) int { case obj.NAME_AUTO: c.instoffset = int64(c.autosize) + a.Offset + if c.instoffset >= -BIG && c.instoffset < BIG { return C_SOREG } @@ -917,13 +941,13 @@ func (c *ctxt9) aclass(a *obj.Addr) int { case obj.NAME_NONE: c.instoffset = a.Offset - if c.instoffset == 0 { + if a.Offset == 0 && a.Index == 0 { return C_ZOREG - } - if c.instoffset >= -BIG && c.instoffset < BIG { + } else if c.instoffset >= -BIG && c.instoffset < BIG { return C_SOREG + } else { + return C_LOREG } - return C_LOREG } return C_GOK @@ -1160,6 +1184,9 @@ func cmp(a int, b int) bool { case C_LOREG: return cmp(C_SOREG, b) + case C_XOREG: + return cmp(C_REG, b) || cmp(C_ZOREG, b) + // An even/odd register input always matches the regular register types. case C_REG: return cmp(C_REGP, b) || (b == C_ZCON && r0iszero != 0) @@ -2562,22 +2589,15 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { r = c.getimpliedreg(&p.To, p) } v := c.regoff(&p.To) - if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 { - if v != 0 { - c.ctxt.Diag("illegal indexed instruction\n%v", p) - } - o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r)) - } else { - if int32(int16(v)) != v { - log.Fatalf("mishandled instruction %v", p) - } - // Offsets in DS form stores must be a multiple of 4 - inst := c.opstore(p.As) - if c.opform(inst) == DS_FORM && v&0x3 != 0 { - log.Fatalf("invalid offset for DS form load/store %v", p) - } - o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v)) + if int32(int16(v)) != v { + log.Fatalf("mishandled instruction %v", p) } + // Offsets in DS form stores must be a multiple of 4 + inst := c.opstore(p.As) + if c.opform(inst) == DS_FORM && v&0x3 != 0 { + log.Fatalf("invalid offset for DS form load/store %v", p) + } + o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v)) case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */ r := int(p.From.Reg) @@ -2586,22 +2606,15 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { r = c.getimpliedreg(&p.From, p) } v := c.regoff(&p.From) - if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 { - if v != 0 { - c.ctxt.Diag("illegal indexed instruction\n%v", p) - } - o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) - } else { - if int32(int16(v)) != v { - log.Fatalf("mishandled instruction %v", p) - } - // Offsets in DS form loads must be a multiple of 4 - inst := c.opload(p.As) - if c.opform(inst) == DS_FORM && v&0x3 != 0 { - log.Fatalf("invalid offset for DS form load/store %v", p) - } - o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v)) + if int32(int16(v)) != v { + log.Fatalf("mishandled instruction %v", p) + } + // Offsets in DS form loads must be a multiple of 4 + inst := c.opload(p.As) + if c.opform(inst) == DS_FORM && v&0x3 != 0 { + log.Fatalf("invalid offset for DS form load/store %v", p) } + o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v)) // Sign extend MOVB operations. This is ignored for other cases (o.size == 4). o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) @@ -3141,9 +3154,16 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 = uint32(c.regoff(&p.From)) case 41: /* stswi */ + if p.To.Type == obj.TYPE_MEM && p.To.Index == 0 && p.To.Offset != 0 { + c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As) + } + o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11 case 42: /* lswi */ + if p.From.Type == obj.TYPE_MEM && p.From.Index == 0 && p.From.Offset != 0 { + c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As) + } o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */ @@ -3772,6 +3792,17 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { if so&0x3 != 0 { log.Fatalf("invalid offset for DS form load/store %v", p) } + + case 108: /* mov r, xoreg ==> stwx rx,ry */ + r := int(p.To.Reg) + o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r)) + + case 109: /* mov xoreg, r ==> lbzx/lhzx/lwzx rx,ry, lbzx rx,ry + extsb r,r */ + r := int(p.From.Reg) + + o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) + // Sign extend MOVB operations. This is ignored for other cases (o.size == 4). + o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) } out[0] = o1 diff --git a/src/cmd/internal/obj/ppc64/asm_test.go b/src/cmd/internal/obj/ppc64/asm_test.go index c16d4a6e73..15dde3a952 100644 --- a/src/cmd/internal/obj/ppc64/asm_test.go +++ b/src/cmd/internal/obj/ppc64/asm_test.go @@ -482,6 +482,7 @@ func TestAddrClassifier(t *testing.T) { {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: BIG}, C_LOREG}, {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LOREG}, // 33 is FixedFrameSize-1 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE}, C_ZOREG}, + {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Index: REG_R4}, C_XOREG}, {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: 1}, C_SOREG}, {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: BIG}, C_LOREG}, {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: -BIG - 33}, C_LOREG}, |
