{ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
{AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
{AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
+ {AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 107, 4, 0, 0, 0},
+ {AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 107, 4, 0, 0, 0},
{AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
{ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
+ {ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 107, 4, 0, 0, 0},
{ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 26, 4, 0, 0, 0},
{AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
{AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
- {AMVN, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
{AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
{AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
c.ctxt.Diag("illegal destination register: %v\n", p)
}
o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
+
+ case 107: // op R<<n, RSP, RSP (extended register)
+ // Refer to ARM reference manual, if "Rd" or "Rn" is RSP,
+ // it can be encoded as op(extended regster) instruction.
+ if !(p.To.Reg == REGSP || p.Reg == REGSP) {
+ c.ctxt.Diag("expected SP reference: %v", p)
+ break
+ }
+ if p.To.Reg == REGSP && (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) {
+ c.ctxt.Diag("unexpected SP reference: %v", p)
+ break
+ }
+ amount := (p.From.Offset >> 10) & 63
+ shift := (p.From.Offset >> 22) & 3
+ if shift != 0 {
+ c.ctxt.Diag("illegal combination: %v", p)
+ break
+ }
+
+ if amount > 4 {
+ c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p)
+ break
+ }
+ rf := (p.From.Offset >> 16) & 31
+ rt := int(p.To.Reg)
+ r := int(p.Reg)
+ if p.To.Type == obj.TYPE_NONE {
+ rt = REGZERO
+ }
+ if r == 0 {
+ r = rt
+ }
+
+ o1 = c.opxrrr(p, p.As, false)
+ o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31)
}
out[0] = o1
out[1] = o2
func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 {
extension := uint32(0)
if !extend {
- switch a {
- case AADD, ACMN, AADDS, ASUB, ACMP, ASUBS:
+ if isADDop(a) {
extension = LSL0_64
-
- case AADDW, ACMNW, AADDSW, ASUBW, ACMPW, ASUBSW:
+ }
+ if isADDWop(a) {
extension = LSL0_32
}
}