// {
// outcode($1, $2, &$3, 0, &$5);
// }
- CLZ.S R1, R2
+ CLZ R1, R2
//
// MOVW
// {
// outcode($1, $2, &$3, $5, &nullgen);
// }
- CMP.S $1, R2
- CMP.S R1<<R2, R3
- CMP.S R1, R2
+ CMP $1, R2
+ CMP R1<<R2, R3
+ CMP R1, R2
//
// MOVM
// }
MOVM 0(R1), [R2,R5,R8,g] // MOVM (R1), [R2,R5,R8,g]
MOVM (R1), [R2-R5] // MOVM (R1), [R2,R3,R4,R5]
- MOVM.S (R1), [R2]
+ MOVM (R1), [R2]
// LTYPE8 cond '[' reglist ']' ',' ioreg
// {
// }
MOVM [R2,R5,R8,g], 0(R1) // MOVM [R2,R5,R8,g], (R1)
MOVM [R2-R5], (R1) // MOVM [R2,R3,R4,R5], (R1)
- MOVM.S [R2], (R1)
+ MOVM [R2], (R1)
//
// SWAP
// {
// outcode($1, $2, &$5, int32($3.Reg), &$7);
// }
- STREX.S R1, (R2), R3 // STREX.S (R2), R1, R3
+ STREX R1, (R2), R3 // STREX (R2), R1, R3
// LTYPE9 cond reg ',' ireg
// {
// outcode($1, $2, &$5, int32($3.Reg), &$3);
// }
- STREX.S R1, (R2) // STREX.S (R2), R1, R1
+ STREX R1, (R2) // STREX (R2), R1, R1
// LTYPE9 cond comma ireg ',' reg
// {
// outcode($1, $2, &$4, int32($6.Reg), &$6);
// }
- STREX.S (R2), R3 // STREX.S (R2), R3, R3
+ STREX (R2), R3 // STREX (R2), R3, R3
//
// word
// {
// outcode($1, $2, &$3, 0, &$5);
// }
- ABSF.S F1, F2
+ ABSF F1, F2
// LTYPEK cond frcon ',' freg
// {
// outcode($1, $2, &$3, 0, &$5);
// }
- ADDD.S F1, F2
+ ADDD F1, F2
MOVF $0.5, F2 // MOVF $(0.5), F2
// LTYPEK cond frcon ',' LFREG ',' freg
// {
// outcode($1, $2, &$3, $5, &$7);
// }
- ADDD.S F1, F2, F3
+ ADDD F1, F2, F3
// LTYPEL cond freg ',' freg
// {
// outcode($1, $2, &$3, int32($5.Reg), &nullgen);
// }
- CMPD.S F1, F2
+ CMPD F1, F2
//
// MCR MRC
return size
}
+const (
+ T_SBIT = 1 << 0
+ T_PBIT = 1 << 1
+ T_WBIT = 1 << 2
+)
+
+var mayHaveSuffix = map[obj.As]uint8{
+ // bit logic
+ AAND: T_SBIT,
+ AEOR: T_SBIT,
+ AORR: T_SBIT,
+ ABIC: T_SBIT,
+ // arithmatic
+ ASUB: T_SBIT,
+ AADD: T_SBIT,
+ ASBC: T_SBIT,
+ AADC: T_SBIT,
+ ARSB: T_SBIT,
+ ARSC: T_SBIT,
+ // mov
+ AMVN: T_SBIT,
+ AMOVW: T_SBIT | T_PBIT | T_WBIT,
+ AMOVB: T_SBIT | T_PBIT | T_WBIT,
+ AMOVBS: T_SBIT | T_PBIT | T_WBIT,
+ AMOVBU: T_SBIT | T_PBIT | T_WBIT,
+ AMOVH: T_SBIT | T_PBIT | T_WBIT,
+ AMOVHS: T_SBIT | T_PBIT | T_WBIT,
+ AMOVHU: T_SBIT | T_PBIT | T_WBIT,
+ AMOVM: T_PBIT | T_WBIT,
+ // shift
+ ASRL: T_SBIT,
+ ASRA: T_SBIT,
+ ASLL: T_SBIT,
+ // mul
+ AMUL: T_SBIT,
+ AMULU: T_SBIT,
+ AMULL: T_SBIT,
+ AMULLU: T_SBIT,
+ // mula
+ AMULA: T_SBIT,
+ AMULAL: T_SBIT,
+ AMULALU: T_SBIT,
+ // MRC/MCR
+ AMRC: T_SBIT,
+}
+
+func checkBits(ctxt *obj.Link, p *obj.Prog) {
+ if p.Scond&C_SBIT != 0 && mayHaveSuffix[p.As]&T_SBIT == 0 {
+ ctxt.Diag("invalid .S suffix: %v", p)
+ }
+ if p.Scond&C_PBIT != 0 && mayHaveSuffix[p.As]&T_PBIT == 0 {
+ ctxt.Diag("invalid .P suffix: %v", p)
+ }
+ if p.Scond&C_WBIT != 0 && mayHaveSuffix[p.As]&T_WBIT == 0 {
+ ctxt.Diag("invalid .W suffix: %v", p)
+ }
+}
+
func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
var p *obj.Prog
var op *obj.Prog
if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE {
c.flushpool(p, 0, 0)
}
+
+ checkBits(ctxt, p)
+
pc += int32(m)
}
if p.Scond&C_UBIT != 0 {
o1 |= 1 << 23
}
- if p.Scond&C_SBIT != 0 {
- o1 |= 1 << 22
- }
if p.Scond&C_WBIT != 0 {
o1 |= 1 << 21
}
if sc&C_SBIT != 0 {
o |= 1 << 20
}
- if sc&(C_PBIT|C_WBIT) != 0 {
- c.ctxt.Diag(".nil/.W on dp instruction")
- }
switch a {
case ADIVHW:
return o | 0x71<<20 | 0xf<<12 | 0x1<<4
return o | 0xc<<21
case AMOVB, AMOVH, AMOVW:
+ if sc&(C_PBIT|C_WBIT) != 0 {
+ c.ctxt.Diag("invalid .P/.W suffix: %v", p)
+ }
return o | 0xd<<21
case ABIC:
return o | 0xe<<21
}
func (c *ctxt5) opbra(p *obj.Prog, a obj.As, sc int) uint32 {
- if sc&(C_SBIT|C_PBIT|C_WBIT) != 0 {
- c.ctxt.Diag("%v: .nil/.nil/.W on bra instruction", p)
- }
sc &= C_SCOND
sc ^= C_SCOND_XOR
if a == ABL || a == obj.ADUFFZERO || a == obj.ADUFFCOPY {
}
func (c *ctxt5) ofsr(a obj.As, r int, v int32, b int, sc int, p *obj.Prog) uint32 {
- if sc&C_SBIT != 0 {
- c.ctxt.Diag(".nil on FLDR/FSTR instruction: %v", p)
- }
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
if sc&C_PBIT == 0 {
o |= 1 << 24