{as: ASRAD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
{as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
{as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
- {as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
- {as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 102, size: 4},
- {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
- {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 102, size: 4},
+ {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
+ {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 63, size: 4},
{as: ARLWNM, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
- {as: ARLWNM, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 103, size: 4},
+ {as: ARLWNM, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 63, size: 4},
{as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
{as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
{as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
opset(APTESYNC, r0)
opset(ATLBSYNC, r0)
- case ARLWMI:
- opset(ARLWMICC, r0)
-
case ARLWNM:
opset(ARLWNMCC, r0)
+ opset(ARLWMI, r0)
+ opset(ARLWMICC, r0)
case ARLDMI:
opset(ARLDMICC, r0)
/*
* 32-bit masks
*/
-func getmask(m []byte, v uint32) bool {
+func getmask(m *[2]uint32, v uint32) bool {
m[1] = 0
- m[0] = m[1]
+ m[0] = 0
if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
if getmask(m, ^v) {
- i := int(m[0])
+ i := m[0]
m[0] = m[1] + 1
- m[1] = byte(i - 1)
+ m[1] = i - 1
return true
}
for i := 0; i < 32; i++ {
if v&(1<<uint(31-i)) != 0 {
- m[0] = byte(i)
+ m[0] = uint32(i)
for {
- m[1] = byte(i)
+ m[1] = uint32(i)
i++
if i >= 32 || v&(1<<uint(31-i)) == 0 {
break
return false
}
-func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
- if !getmask(m, v) {
+func (c *ctxt9) maskgen(p *obj.Prog, v uint32) (mb, me uint32) {
+ var m [2]uint32
+ if !getmask(&m, v) {
c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
}
+ return m[0], m[1]
}
/*
v := c.regoff(&p.To)
o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
- case 62: /* rlwmi $sh,s,$mask,a */
+ case 62: /* clrlslwi $sh,s,$mask,a */
v := c.regoff(&p.From)
- switch p.As {
- case ACLRLSLWI:
- n := c.regoff(p.GetFrom3())
- // This is an extended mnemonic described in the ISA C.8.2
- // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n
- // It maps onto rlwinm which is directly generated here.
- if n > v || v >= 32 {
- c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p)
- }
-
- o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n))
- default:
- var mask [2]uint8
- c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
- o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
- o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
+ n := c.regoff(p.GetFrom3())
+ // This is an extended mnemonic described in the ISA C.8.2
+ // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n
+ // It maps onto rlwinm which is directly generated here.
+ if n > v || v >= 32 {
+ c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p)
}
- case 63: /* rlwmi b,s,$mask,a */
- var mask [2]uint8
- c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
- o1 = AOP_RRR(c.oprrr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
- o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
+ o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n))
+
+ case 63: /* rlwimi/rlwnm/rlwinm [$sh,b],s,[$mask or mb,me],a*/
+ var mb, me uint32
+ if len(p.RestArgs) == 1 { // Mask needs decomposed into mb and me.
+ mb, me = c.maskgen(p, uint32(p.RestArgs[0].Addr.Offset))
+ } else { // Otherwise, mask is already passed as mb and me in RestArgs.
+ mb, me = uint32(p.RestArgs[0].Addr.Offset), uint32(p.RestArgs[1].Addr.Offset)
+ }
+ if p.From.Type == obj.TYPE_CONST {
+ o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Offset), mb, me)
+ } else {
+ o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
+ }
case 64: /* mtfsf fr[, $m] {,fpcsr} */
var v int32
case 101:
o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
- case 102: /* RLWMI $sh,rs,$mb,$me,rt (M-form opcode)*/
- mb := uint32(c.regoff(&p.RestArgs[0].Addr))
- me := uint32(c.regoff(&p.RestArgs[1].Addr))
- sh := uint32(c.regoff(&p.From))
- o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb, me)
-
- case 103: /* RLWNM rb,rs,$mb,$me,rt (M-form opcode)*/
- mb := uint32(c.regoff(&p.RestArgs[0].Addr))
- me := uint32(c.regoff(&p.RestArgs[1].Addr))
- o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
-
case 104: /* VSX mtvsr* instructions, XX1-form RA,RB,XT */
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))