break
}
- ctxt.Curp = p
p.Pc = int64(c)
o = oplook(ctxt, p)
if ctxt.Headtype != obj.Hnacl {
times++
cursym.Text.Pc = 0 // force re-layout the code.
for p = cursym.Text; p != nil; p = p.Link {
- ctxt.Curp = p
o = oplook(ctxt, p)
if int64(c) > p.Pc {
p.Pc = int64(c)
var v int
for p = p.Link; p != nil; p = p.Link {
ctxt.Pc = p.Pc
- ctxt.Curp = p
o = oplook(ctxt, p)
opc = int32(p.Pc)
if ctxt.Headtype != obj.Hnacl {
}
case 1: /* op R,[R],R */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
rf := int(p.From.Reg)
rt := int(p.To.Reg)
case 2: /* movbu $I,[R],R */
aclass(ctxt, &p.From)
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
rt := int(p.To.Reg)
r := int(p.Reg)
case 4: /* MOVW $off(R), R -> add $off,[R],R */
aclass(ctxt, &p.From)
if ctxt.Instoffset < 0 {
- o1 = oprrr(ctxt, ASUB, int(p.Scond))
+ o1 = oprrr(ctxt, p, ASUB, int(p.Scond))
o1 |= uint32(immrot(uint32(-ctxt.Instoffset)))
} else {
- o1 = oprrr(ctxt, AADD, int(p.Scond))
+ o1 = oprrr(ctxt, p, AADD, int(p.Scond))
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
}
r := int(p.From.Reg)
case 6: /* b ,O(R) -> add $O,R,PC */
aclass(ctxt, &p.To)
- o1 = oprrr(ctxt, AADD, int(p.Scond))
+ o1 = oprrr(ctxt, p, AADD, int(p.Scond))
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
o1 |= (uint32(p.To.Reg) & 15) << 16
o1 |= (REGPC & 15) << 12
if ctxt.Instoffset != 0 {
ctxt.Diag("%v: doesn't support BL offset(REG) with non-zero offset %d", p, ctxt.Instoffset)
}
- o1 = oprrr(ctxt, ABL, int(p.Scond))
+ o1 = oprrr(ctxt, p, ABL, int(p.Scond))
o1 |= (uint32(p.To.Reg) & 15) << 0
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
case 8: /* sll $c,[R],R -> mov (R<<$c),R */
aclass(ctxt, &p.From)
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
o1 |= (uint32(p.To.Reg) & 15) << 12
case 9: /* sll R,[R],R -> mov (R<<R),R */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
r := int(p.Reg)
if r == 0 {
o1 |= (uint32(p.To.Reg) & 15) << 12
case 10: /* swi [$con] */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
if p.To.Type != obj.TYPE_NONE {
aclass(ctxt, &p.To)
o1 = omvl(ctxt, p, &p.From, int(p.To.Reg))
if o.flag&LPCREL != 0 {
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | (uint32(p.To.Reg)&15)<<0 | (REGPC&15)<<16 | (uint32(p.To.Reg)&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | (uint32(p.To.Reg)&15)<<0 | (REGPC&15)<<16 | (uint32(p.To.Reg)&15)<<12
}
case 13: /* op $lcon, [R], R */
if o1 == 0 {
break
}
- o2 = oprrr(ctxt, p.As, int(p.Scond))
+ o2 = oprrr(ctxt, p, p.As, int(p.Scond))
o2 |= REGTMP & 15
r := int(p.Reg)
if p.As == AMOVW || p.As == AMVN {
}
case 14: /* movb/movbu/movh/movhu R,R */
- o1 = oprrr(ctxt, ASLL, int(p.Scond))
+ o1 = oprrr(ctxt, p, ASLL, int(p.Scond))
if p.As == AMOVBU || p.As == AMOVHU {
- o2 = oprrr(ctxt, ASRL, int(p.Scond))
+ o2 = oprrr(ctxt, p, ASRL, int(p.Scond))
} else {
- o2 = oprrr(ctxt, ASRA, int(p.Scond))
+ o2 = oprrr(ctxt, p, ASRA, int(p.Scond))
}
r := int(p.To.Reg)
}
case 15: /* mul r,[r,]r */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o2 = 0
case 17:
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
rf := int(p.From.Reg)
rt := int(p.To.Reg)
rt2 := int(p.To.Offset)
break
}
- o2 = oprrr(ctxt, AADD, int(p.Scond))
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond))
o2 |= REGTMP & 15
r := int(p.From.Reg)
if r == 0 {
if r == 0 {
r = int(o.param)
}
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
o3 = ofsr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p)
case 53: /* floating point load, int32 offset UGLY */
if r == 0 {
r = int(o.param)
}
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
o3 = ofsr(ctxt, p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20
case 54: /* floating point arith */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o1 |= ((uint32(p.From.Reg)&1)+1)<<21 | (uint32(p.To.Reg)&15)<<12 | 1<<20
case 58: /* movbu R,R */
- o1 = oprrr(ctxt, AAND, int(p.Scond))
+ o1 = oprrr(ctxt, p, AAND, int(p.Scond))
o1 |= uint32(immrot(0xff))
rt := int(p.To.Reg)
o2 = osr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond))
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
case 65: /* mov/movbu addr,R */
}
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
case 101: /* movw tlsvar,R, local exec*/
o2 = ofsr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p)
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
case 69: /* floating point load <- ADDR */
o2 = ofsr(ctxt, p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
/* ArmV4 ops: */
}
/*
- o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
+ o1 = oprrr(ctxt, p, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
o2 = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0); // BX R
*/
// p->to.reg may be REGLINK
- o1 = oprrr(ctxt, AADD, int(p.Scond))
+ o1 = oprrr(ctxt, p, AADD, int(p.Scond))
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
o1 |= (uint32(p.To.Reg) & 15) << 16
o1 |= (REGTMP & 15) << 12
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(0)) | (REGPC&15)<<16 | (REGLINK&15)<<12 // mov PC, LR
- o3 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x12fff<<8 | 1<<4 | REGTMP&15 // BX Rtmp
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | uint32(immrot(0)) | (REGPC&15)<<16 | (REGLINK&15)<<12 // mov PC, LR
+ o3 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x12fff<<8 | 1<<4 | REGTMP&15 // BX Rtmp
case 76: /* bx O(R) when returning from fn*/
ctxt.Diag("ABXRET")
case 80: /* fmov zfcon,freg */
if p.As == AMOVD {
o1 = 0xeeb00b00 // VMOV imm 64
- o2 = oprrr(ctxt, ASUBD, int(p.Scond))
+ o2 = oprrr(ctxt, p, ASUBD, int(p.Scond))
} else {
o1 = 0x0eb00a00 // VMOV imm 32
- o2 = oprrr(ctxt, ASUBF, int(p.Scond))
+ o2 = oprrr(ctxt, p, ASUBF, int(p.Scond))
}
v := int32(0x70) // 1.0
o1 |= (uint32(v) & 0xf0) << 12
case 82: /* fcmp freg,freg, */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.Reg)&15)<<12 | (uint32(p.From.Reg)&15)<<0
o2 = 0x0ef1fa10 // VMRS R15
o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
case 83: /* fcmp freg,, */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.From.Reg)&15)<<12 | 1<<16
o2 = 0x0ef1fa10 // VMRS R15
o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
case 84: /* movfw freg,freg - truncate float-to-fix */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 0
o1 |= (uint32(p.To.Reg) & 15) << 12
case 85: /* movwf freg,freg - fix-to-float */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 0
o1 |= (uint32(p.To.Reg) & 15) << 12
// macro for movfw freg,FTMP; movw FTMP,reg
case 86: /* movfw freg,reg - truncate float-to-fix */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 0
o1 |= (FREGTMP & 15) << 12
- o2 = oprrr(ctxt, -AMOVFW, int(p.Scond))
+ o2 = oprrr(ctxt, p, -AMOVFW, int(p.Scond))
o2 |= (FREGTMP & 15) << 16
o2 |= (uint32(p.To.Reg) & 15) << 12
// macro for movw reg,FTMP; movwf FTMP,freg
case 87: /* movwf reg,freg - fix-to-float */
- o1 = oprrr(ctxt, -AMOVWF, int(p.Scond))
+ o1 = oprrr(ctxt, p, -AMOVWF, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 12
o1 |= (FREGTMP & 15) << 16
- o2 = oprrr(ctxt, p.As, int(p.Scond))
+ o2 = oprrr(ctxt, p, p.As, int(p.Scond))
o2 |= (FREGTMP & 15) << 0
o2 |= (uint32(p.To.Reg) & 15) << 12
case 88: /* movw reg,freg */
- o1 = oprrr(ctxt, -AMOVWF, int(p.Scond))
+ o1 = oprrr(ctxt, p, -AMOVWF, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 12
o1 |= (uint32(p.To.Reg) & 15) << 16
case 89: /* movw freg,reg */
- o1 = oprrr(ctxt, -AMOVFW, int(p.Scond))
+ o1 = oprrr(ctxt, p, -AMOVFW, int(p.Scond))
o1 |= (uint32(p.From.Reg) & 15) << 16
o1 |= (uint32(p.To.Reg) & 15) << 12
}
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
case 94: /* movh/movhu R,addr -> strh */
o2 = oshr(ctxt, int(p.From.Reg), 0, REGTMP, int(p.Scond))
if o.flag&LPCREL != 0 {
o3 = o2
- o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
+ o2 = oprrr(ctxt, p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
}
case 95: /* PLD off(reg) */
o1 = 0xf7fabcfd
case 97: /* CLZ Rm, Rd */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.To.Reg) & 15) << 12
o1 |= (uint32(p.From.Reg) & 15) << 0
case 98: /* MULW{T,B} Rs, Rm, Rd */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.To.Reg) & 15) << 16
o1 |= (uint32(p.From.Reg) & 15) << 8
o1 |= (uint32(p.Reg) & 15) << 0
case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
- o1 = oprrr(ctxt, p.As, int(p.Scond))
+ o1 = oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= (uint32(p.To.Reg) & 15) << 12
o1 |= (uint32(p.From.Reg) & 15) << 8
func mov(ctxt *obj.Link, p *obj.Prog) uint32 {
aclass(ctxt, &p.From)
- o1 := oprrr(ctxt, p.As, int(p.Scond))
+ o1 := oprrr(ctxt, p, p.As, int(p.Scond))
o1 |= uint32(p.From.Offset)
rt := int(p.To.Reg)
if p.To.Type == obj.TYPE_NONE {
return o1
}
-func oprrr(ctxt *obj.Link, a obj.As, sc int) uint32 {
+func oprrr(ctxt *obj.Link, p *obj.Prog, a obj.As, sc int) uint32 {
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
if sc&C_SBIT != 0 {
o |= 1 << 20
return o&(0xf<<28) | 0x12fff3<<4
}
- ctxt.Diag("%v: bad rrr %d", ctxt.Curp, a)
+ ctxt.Diag("%v: bad rrr %d", p, a)
return 0
}
return 0xe<<28 | 0x5<<25
}
- ctxt.Diag("%v: bad bra %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad bra %v", p, a)
return 0
}
return 0
}
- o1 = oprrr(ctxt, AMVN, int(p.Scond)&C_SCOND)
+ o1 = oprrr(ctxt, p, AMVN, int(p.Scond)&C_SCOND)
o1 |= uint32(v)
o1 |= (uint32(dr) & 15) << 12
} else {
var m int
var o *Optab
for p = p.Link; p != nil; p = p.Link {
- ctxt.Curp = p
if p.As == ADWORD && (c&7) != 0 {
c += 4
}
var out [6]uint32
for p := cursym.Text.Link; p != nil; p = p.Link {
ctxt.Pc = p.Pc
- ctxt.Curp = p
o = oplook(ctxt, p)
// need to align DWORDs on 8-byte boundary. The ISA doesn't
* return the offset value to use in the instruction,
* scaled if necessary
*/
-func offsetshift(ctxt *obj.Link, v int64, c int) int64 {
+func offsetshift(ctxt *obj.Link, p *obj.Prog, v int64, c int) int64 {
s := 0
if c >= C_SEXT1 && c <= C_SEXT16 {
s = c - C_SEXT1
}
vs := v >> uint(s)
if vs<<uint(s) != v {
- ctxt.Diag("odd offset: %d\n%v", v, ctxt.Curp)
+ ctxt.Diag("odd offset: %d\n%v", v, p)
}
return vs
}
break
case 1: /* op Rm,[Rn],Rd; default Rn=Rd -> op Rm<<0,[Rn,]Rd (shifted register) */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
rt := int(p.To.Reg)
if p.To.Type == obj.TYPE_NONE {
r = rt
}
v := int32(regoff(ctxt, &p.From))
- o1 = oaddi(ctxt, int32(o1), v, r, rt)
+ o1 = oaddi(ctxt, p, int32(o1), v, r, rt)
case 3: /* op R<<n[,R],R (shifted register) */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
rt := int(p.To.Reg)
o1 |= (uint32(r&31) << 5) | uint32(rt&31)
case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
rt := int(p.To.Reg)
r := int(o.param)
o1 |= ((uint32(v) & 0xFFF) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
case 5: /* b s; bl s */
- o1 = opbra(ctxt, p.As)
+ o1 = opbra(ctxt, p, p.As)
if p.To.Sym == nil {
o1 |= uint32(brdist(ctxt, p, 0, 26, 2))
rel.Type = obj.R_CALLARM64
case 6: /* b ,O(R); bl ,O(R) */
- o1 = opbrr(ctxt, p.As)
+ o1 = opbrr(ctxt, p, p.As)
o1 |= uint32(p.To.Reg&31) << 5
rel := obj.Addrel(ctxt.Cursym)
rel.Type = obj.R_CALLIND
case 7: /* beq s */
- o1 = opbra(ctxt, p.As)
+ o1 = opbra(ctxt, p, p.As)
o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5)
v := int32(p.From.Offset)
switch p.As {
case AASR:
- o1 = opbfm(ctxt, ASBFM, int(v), 63, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, int(v), 63, rf, rt)
case AASRW:
- o1 = opbfm(ctxt, ASBFMW, int(v), 31, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFMW, int(v), 31, rf, rt)
case ALSL:
- o1 = opbfm(ctxt, AUBFM, int((64-v)&63), int(63-v), rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, int((64-v)&63), int(63-v), rf, rt)
case ALSLW:
- o1 = opbfm(ctxt, AUBFMW, int((32-v)&31), int(31-v), rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, int((32-v)&31), int(31-v), rf, rt)
case ALSR:
- o1 = opbfm(ctxt, AUBFM, int(v), 63, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, int(v), 63, rf, rt)
case ALSRW:
- o1 = opbfm(ctxt, AUBFMW, int(v), 31, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, int(v), 31, rf, rt)
case AROR:
- o1 = opextr(ctxt, AEXTR, v, rf, rf, rt)
+ o1 = opextr(ctxt, p, AEXTR, v, rf, rf, rt)
case ARORW:
- o1 = opextr(ctxt, AEXTRW, v, rf, rf, rt)
+ o1 = opextr(ctxt, p, AEXTRW, v, rf, rf, rt)
default:
- ctxt.Diag("bad shift $con\n%v", ctxt.Curp)
+ ctxt.Diag("bad shift $con\n%v", p)
break
}
case 9: /* lsl Rm,[Rn],Rd -> lslv Rm, Rn, Rd */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
r := int(p.Reg)
if r == 0 {
o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31)
case 10: /* brk/hvc/.../svc [$con] */
- o1 = opimm(ctxt, p.As)
+ o1 = opimm(ctxt, p, p.As)
if p.To.Type != obj.TYPE_NONE {
o1 |= uint32((p.To.Offset & 0xffff) << 5)
r = rt
}
if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
- o2 = opxrrr(ctxt, p.As)
+ o2 = opxrrr(ctxt, p, p.As)
o2 |= REGTMP & 31 << 16
o2 |= LSL0_64
} else {
- o2 = oprrr(ctxt, p.As)
+ o2 = oprrr(ctxt, p, p.As)
o2 |= REGTMP & 31 << 16 /* shift is 0 */
}
}
case 15: /* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,Ra,Rd */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
case 16: /* XremY R[,R],R -> XdivY; XmsubY */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf := int(p.From.Reg)
rt := int(p.To.Reg)
r = rt
}
o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31
- o2 = oprrr(ctxt, AMSUBW)
+ o2 = oprrr(ctxt, p, AMSUBW)
o2 |= o1 & (1 << 31) /* same size */
o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31)
case 17: /* op Rm,[Rn],Rd; default Rn=ZR */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
case 18: /* csel cond,Rn,Rm,Rd; cinc/cinv/cneg cond,Rn,Rd; cset cond,Rd */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
cond := int(p.From.Reg)
r := int(p.Reg)
cond := int(p.From.Reg)
var rf int
if p.From3.Type == obj.TYPE_REG {
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf = int(p.From3.Reg) /* Rm */
} else {
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
rf = int(p.From3.Offset & 0x1F)
}
r = int(o.param)
}
if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
- o1 = olsr9s(ctxt, int32(opstr9(ctxt, p.As)), v, r, int(p.From.Reg))
+ o1 = olsr9s(ctxt, p, int32(opstr9(ctxt, p, p.As)), v, r, int(p.From.Reg))
} else {
- v = int32(offsetshift(ctxt, int64(v), int(o.a3)))
- o1 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), v, r, int(p.From.Reg))
+ v = int32(offsetshift(ctxt, p, int64(v), int(o.a3)))
+ o1 = olsr12u(ctxt, p, int32(opstr12(ctxt, p, p.As)), v, r, int(p.From.Reg))
}
case 21: /* movT O(R),R -> ldrT */
r = int(o.param)
}
if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
- o1 = olsr9s(ctxt, int32(opldr9(ctxt, p.As)), v, r, int(p.To.Reg))
+ o1 = olsr9s(ctxt, p, int32(opldr9(ctxt, p, p.As)), v, r, int(p.To.Reg))
} else {
- v = int32(offsetshift(ctxt, int64(v), int(o.a1)))
+ v = int32(offsetshift(ctxt, p, int64(v), int(o.a1)))
//print("offset=%lld v=%ld a1=%d\n", instoffset, v, o->a1);
- o1 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), v, r, int(p.To.Reg))
+ o1 = olsr12u(ctxt, p, int32(opldr12(ctxt, p, p.As)), v, r, int(p.To.Reg))
}
case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
if v < -256 || v > 255 {
ctxt.Diag("offset out of range\n%v", p)
}
- o1 = opldrpp(ctxt, p.As)
+ o1 = opldrpp(ctxt, p, p.As)
if o.scond == C_XPOST {
o1 |= 1 << 10
} else {
if v < -256 || v > 255 {
ctxt.Diag("offset out of range\n%v", p)
}
- o1 = LD2STR(opldrpp(ctxt, p.As))
+ o1 = LD2STR(opldrpp(ctxt, p, p.As))
if o.scond == C_XPOST {
o1 |= 1 << 10
} else {
if s {
ctxt.Diag("illegal SP reference\n%v", p)
}
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
} else if s {
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
} else {
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
}
case 25: /* negX Rs, Rd -> subX Rs<<0, ZR, Rd */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
rf := int(p.From.Reg)
if rf == C_NONE {
o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
case 26: /* negX Rm<<s, Rd -> subX Rm<<s, ZR, Rd */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
rt := int(p.To.Reg)
o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
case 27: /* op Rm<<n[,Rn],Rd (extended register) */
- o1 = opxrrr(ctxt, p.As)
+ o1 = opxrrr(ctxt, p, p.As)
if (p.From.Reg-obj.RBaseARM64)®_EXT != 0 {
ctxt.Diag("extended register not implemented\n%v", p)
if r == 0 {
r = int(p.To.Reg)
}
- o2 = oprrr(ctxt, p.As)
+ o2 = oprrr(ctxt, p, p.As)
o2 |= REGTMP & 31 << 16 /* shift is 0 */
o2 |= uint32(r&31) << 5
o2 |= uint32(p.To.Reg & 31)
o1 |= 1 << 16 // FMOV Rx, Fy
}
} else {
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
}
o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
if r == 0 {
r = int(o.param)
}
- o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP)
- o2 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg))
+ o1 = oaddi(ctxt, p, int32(opirr(ctxt, p, AADD)), hi, r, REGTMP)
+ o2 = olsr12u(ctxt, p, int32(opstr12(ctxt, p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg))
case 31: /* movT L(R), R -> ldrT */
s := movesize(o.as)
if r == 0 {
r = int(o.param)
}
- o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg))
+ o1 = oaddi(ctxt, p, int32(opirr(ctxt, p, AADD)), hi, r, REGTMP)
+ o2 = olsr12u(ctxt, p, int32(opldr12(ctxt, p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg))
case 32: /* mov $con, R -> movz/movn */
o1 = omovconst(ctxt, p.As, p, &p.From, int(p.To.Reg))
case 33: /* movk $uimm16 << pos */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
d := p.From.Offset
if (d >> 16) != 0 {
if !(o1 != 0) {
break
}
- o2 = opxrrr(ctxt, AADD)
+ o2 = opxrrr(ctxt, p, AADD)
o2 |= REGTMP & 31 << 16
o2 |= LSL0_64
r := int(p.From.Reg)
o2 |= uint32(p.To.Reg & 31)
case 35: /* mov SPR,R -> mrs */
- o1 = oprrr(ctxt, AMRS)
+ o1 = oprrr(ctxt, p, AMRS)
v := int32(p.From.Offset)
if (o1 & uint32(v&^(3<<19))) != 0 {
o1 |= uint32(p.To.Reg & 31)
case 36: /* mov R,SPR */
- o1 = oprrr(ctxt, AMSR)
+ o1 = oprrr(ctxt, p, AMSR)
v := int32(p.To.Offset)
if (o1 & uint32(v&^(3<<19))) != 0 {
if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 {
ctxt.Diag("illegal immediate for PSTATE field\n%v", p)
}
- o1 = opirr(ctxt, AMSR)
+ o1 = opirr(ctxt, p, AMSR)
o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
v := int32(0)
for i := 0; i < len(pstatefield); i++ {
o1 |= uint32(v)
case 38: /* clrex [$imm] */
- o1 = opimm(ctxt, p.As)
+ o1 = opimm(ctxt, p, p.As)
if p.To.Type == obj.TYPE_NONE {
o1 |= 0xF << 8
}
case 39: /* cbz R, rel */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
o1 |= uint32(p.From.Reg & 31)
o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5)
case 40: /* tbz */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
v := int32(p.From.Offset)
if v < 0 || v > 63 {
o1 |= uint32(p.Reg)
case 41: /* eret, nop, others with no operands */
- o1 = op0(ctxt, p.As)
+ o1 = op0(ctxt, p, p.As)
case 42: /* bfm R,r,s,R */
- o1 = opbfm(ctxt, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg))
+ o1 = opbfm(ctxt, p, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg))
case 43: /* bfm aliases */
r := int(p.From.Offset)
}
switch p.As {
case ABFI:
- o1 = opbfm(ctxt, ABFM, 64-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ABFM, 64-r, s-1, rf, rt)
case ABFIW:
- o1 = opbfm(ctxt, ABFMW, 32-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ABFMW, 32-r, s-1, rf, rt)
case ABFXIL:
- o1 = opbfm(ctxt, ABFM, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ABFM, r, r+s-1, rf, rt)
case ABFXILW:
- o1 = opbfm(ctxt, ABFMW, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ABFMW, r, r+s-1, rf, rt)
case ASBFIZ:
- o1 = opbfm(ctxt, ASBFM, 64-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, 64-r, s-1, rf, rt)
case ASBFIZW:
- o1 = opbfm(ctxt, ASBFMW, 32-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFMW, 32-r, s-1, rf, rt)
case ASBFX:
- o1 = opbfm(ctxt, ASBFM, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, r, r+s-1, rf, rt)
case ASBFXW:
- o1 = opbfm(ctxt, ASBFMW, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFMW, r, r+s-1, rf, rt)
case AUBFIZ:
- o1 = opbfm(ctxt, AUBFM, 64-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, 64-r, s-1, rf, rt)
case AUBFIZW:
- o1 = opbfm(ctxt, AUBFMW, 32-r, s-1, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, 32-r, s-1, rf, rt)
case AUBFX:
- o1 = opbfm(ctxt, AUBFM, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, r, r+s-1, rf, rt)
case AUBFXW:
- o1 = opbfm(ctxt, AUBFMW, r, r+s-1, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, r, r+s-1, rf, rt)
default:
- ctxt.Diag("bad bfm alias\n%v", ctxt.Curp)
+ ctxt.Diag("bad bfm alias\n%v", p)
break
}
case 44: /* extr $b, Rn, Rm, Rd */
- o1 = opextr(ctxt, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg))
+ o1 = opextr(ctxt, p, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg))
case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */
rf := int(p.From.Reg)
}
switch as {
case AMOVB, ASXTB:
- o1 = opbfm(ctxt, ASBFM, 0, 7, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, 0, 7, rf, rt)
case AMOVH, ASXTH:
- o1 = opbfm(ctxt, ASBFM, 0, 15, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, 0, 15, rf, rt)
case AMOVW, ASXTW:
- o1 = opbfm(ctxt, ASBFM, 0, 31, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFM, 0, 31, rf, rt)
case AMOVBU, AUXTB:
- o1 = opbfm(ctxt, AUBFM, 0, 7, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, 0, 7, rf, rt)
case AMOVHU, AUXTH:
- o1 = opbfm(ctxt, AUBFM, 0, 15, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, 0, 15, rf, rt)
case AMOVWU:
- o1 = oprrr(ctxt, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
+ o1 = oprrr(ctxt, p, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
case AUXTW:
- o1 = opbfm(ctxt, AUBFM, 0, 31, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFM, 0, 31, rf, rt)
case ASXTBW:
- o1 = opbfm(ctxt, ASBFMW, 0, 7, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFMW, 0, 7, rf, rt)
case ASXTHW:
- o1 = opbfm(ctxt, ASBFMW, 0, 15, rf, rt)
+ o1 = opbfm(ctxt, p, ASBFMW, 0, 15, rf, rt)
case AUXTBW:
- o1 = opbfm(ctxt, AUBFMW, 0, 7, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, 0, 7, rf, rt)
case AUXTHW:
- o1 = opbfm(ctxt, AUBFMW, 0, 15, rf, rt)
+ o1 = opbfm(ctxt, p, AUBFMW, 0, 15, rf, rt)
default:
ctxt.Diag("bad sxt %v", as)
}
case 46: /* cls */
- o1 = opbit(ctxt, p.As)
+ o1 = opbit(ctxt, p, p.As)
o1 |= uint32(p.From.Reg&31) << 5
o1 |= uint32(p.To.Reg & 31)
if r == 0 {
r = int(o.param)
}
- o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.From.Reg))
+ o2 = olsxrr(ctxt, p, p.As, REGTMP, r, int(p.From.Reg))
case 48: /* movT V(R), R -> ldrT (huge offset) */
o1 = omovlit(ctxt, AMOVW, p, &p.From, REGTMP)
if r == 0 {
r = int(o.param)
}
- o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.To.Reg))
+ o2 = olsxrr(ctxt, p, p.As, REGTMP, r, int(p.To.Reg))
case 50: /* sys/sysl */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 {
ctxt.Diag("illegal SYS argument\n%v", p)
}
case 51: /* dmb */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
if p.From.Type == obj.TYPE_CONST {
o1 |= uint32((p.From.Offset & 0xF) << 8)
}
case 52: /* hint */
- o1 = opirr(ctxt, p.As)
+ o1 = opirr(ctxt, p, p.As)
o1 |= uint32((p.From.Offset & 0x7F) << 5)
v = ^v
mode = 32
}
- o1 = opirr(ctxt, a)
+ o1 = opirr(ctxt, p, a)
o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31)
case 54: /* floating point arith */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
var rf int
if p.From.Type == obj.TYPE_CONST {
o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
case 56: /* floating point compare */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
var rf int
if p.From.Type == obj.TYPE_CONST {
o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5
case 57: /* floating point conditional compare */
- o1 = oprrr(ctxt, p.As)
+ o1 = oprrr(ctxt, p, p.As)
cond := int(p.From.Reg)
nzcv := int(p.To.Offset)
o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
case 58: /* ldar/ldxr/ldaxr */
- o1 = opload(ctxt, p.As)
+ o1 = opload(ctxt, p, p.As)
o1 |= 0x1F << 16
o1 |= uint32(p.From.Reg) << 5
o1 |= uint32(p.To.Reg & 31)
case 59: /* stxr/stlxr */
- o1 = opstore(ctxt, p.As)
+ o1 = opstore(ctxt, p, p.As)
if p.RegTo2 != obj.REG_NONE {
o1 |= uint32(p.RegTo2&31) << 16
r = rt
}
if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
- o2 = opxrrr(ctxt, p.As)
+ o2 = opxrrr(ctxt, p, p.As)
o2 |= REGTMP & 31 << 16
o2 |= LSL0_64
} else {
- o2 = oprrr(ctxt, p.As)
+ o2 = oprrr(ctxt, p, p.As)
o2 |= REGTMP & 31 << 16 /* shift is 0 */
}
o2 |= uint32(r&31) << 5
/* reloc ops */
case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */
o1 = ADR(1, 0, REGTMP)
- o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31
+ o2 = opirr(ctxt, p, AADD) | REGTMP&31<<5 | REGTMP&31
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
rel.Sym = p.To.Sym
rel.Add = p.To.Offset
rel.Type = obj.R_ADDRARM64
- o3 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), 0, REGTMP, int(p.From.Reg))
+ o3 = olsr12u(ctxt, p, int32(opstr12(ctxt, p, p.As)), 0, REGTMP, int(p.From.Reg))
case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */
o1 = ADR(1, 0, REGTMP)
- o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31
+ o2 = opirr(ctxt, p, AADD) | REGTMP&31<<5 | REGTMP&31
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
rel.Type = obj.R_ADDRARM64
- o3 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), 0, REGTMP, int(p.To.Reg))
+ o3 = olsr12u(ctxt, p, int32(opldr12(ctxt, p, p.As)), 0, REGTMP, int(p.To.Reg))
case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
v := int32(p.From.Offset)
ctxt.Diag("invalid load of 32-bit address: %v", p)
}
o1 = ADR(1, 0, uint32(p.To.Reg))
- o2 = opirr(ctxt, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
+ o2 = opirr(ctxt, p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
rel.Type = obj.R_ADDRARM64
case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
- o1 = opirr(ctxt, AMOVZ)
+ o1 = opirr(ctxt, p, AMOVZ)
o1 |= uint32(p.To.Reg & 31)
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
o1 = ADR(1, 0, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg))
+ o2 = olsr12u(ctxt, p, int32(opldr12(ctxt, p, AMOVD)), 0, REGTMP, int(p.To.Reg))
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */
o1 = ADR(1, 0, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg))
+ o2 = olsr12u(ctxt, p, int32(opldr12(ctxt, p, AMOVD)), 0, REGTMP, int(p.To.Reg))
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
* also op Rn -> Rt
* also Rm*Rn op Ra -> Rd
*/
-func oprrr(ctxt *obj.Link, a obj.As) uint32 {
+func oprrr(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case AADC:
return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
return FPOP1S(0, 0, 3, 5)
}
- ctxt.Diag("%v: bad rrr %d %v", ctxt.Curp, a, a)
+ ctxt.Diag("%v: bad rrr %d %v", p, a, a)
return 0
}
* imm -> Rd
* imm op Rn -> Rd
*/
-func opirr(ctxt *obj.Link, a obj.As) uint32 {
+func opirr(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
/* op $addcon, Rn, Rd */
case AMOVD, AADD:
return SYSOP(0, 0, 3, 2, 0, 0, 0x1F)
}
- ctxt.Diag("%v: bad irr %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad irr %v", p, a)
return 0
}
-func opbit(ctxt *obj.Link, a obj.As) uint32 {
+func opbit(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ACLS:
return S64 | OPBIT(5)
return S64 | OPBIT(2)
default:
- ctxt.Diag("bad bit op\n%v", ctxt.Curp)
+ ctxt.Diag("bad bit op\n%v", p)
return 0
}
}
/*
* add/subtract extended register
*/
-func opxrrr(ctxt *obj.Link, a obj.As) uint32 {
+func opxrrr(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case AADD:
return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
}
- ctxt.Diag("bad opxrrr %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opxrrr %v\n%v", a, p)
return 0
}
-func opimm(ctxt *obj.Link, a obj.As) uint32 {
+func opimm(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ASVC:
return 0xD4<<24 | 0<<21 | 1 /* imm16<<5 */
return SYSOP(0, 0, 3, 3, 0, 2, 0x1F)
}
- ctxt.Diag("%v: bad imm %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad imm %v", p, a)
return 0
}
/*
* pc-relative branches
*/
-func opbra(ctxt *obj.Link, a obj.As) uint32 {
+func opbra(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ABEQ:
return OPBcc(0x0)
return 1<<31 | 5<<26
}
- ctxt.Diag("%v: bad bra %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad bra %v", p, a)
return 0
}
-func opbrr(ctxt *obj.Link, a obj.As) uint32 {
+func opbrr(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ABL:
return OPBLR(1) /* BLR */
return OPBLR(2) /* RET */
}
- ctxt.Diag("%v: bad brr %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad brr %v", p, a)
return 0
}
-func op0(ctxt *obj.Link, a obj.As) uint32 {
+func op0(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ADRPS:
return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5
return SYSHINT(5)
}
- ctxt.Diag("%v: bad op0 %v", ctxt.Curp, a)
+ ctxt.Diag("%v: bad op0 %v", p, a)
return 0
}
/*
* register offset
*/
-func opload(ctxt *obj.Link, a obj.As) uint32 {
+func opload(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ALDAR:
return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10
return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
}
- ctxt.Diag("bad opload %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opload %v\n%v", a, p)
return 0
}
-func opstore(ctxt *obj.Link, a obj.As) uint32 {
+func opstore(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case ASTLR:
return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10
return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
}
- ctxt.Diag("bad opstore %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opstore %v\n%v", a, p)
return 0
}
* load/store register (unsigned immediate) C3.3.13
* these produce 64-bit values (when there's an option)
*/
-func olsr12u(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 {
+func olsr12u(ctxt *obj.Link, p *obj.Prog, o int32, v int32, b int, r int) uint32 {
if v < 0 || v >= (1<<12) {
- ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp)
+ ctxt.Diag("offset out of range: %d\n%v", v, p)
}
o |= (v & 0xFFF) << 10
o |= int32(b&31) << 5
return uint32(o)
}
-func opldr12(ctxt *obj.Link, a obj.As) uint32 {
+func opldr12(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case AMOVD:
return LDSTR12U(3, 0, 1) /* imm12<<10 | Rn<<5 | Rt */
return LDSTR12U(3, 1, 1)
}
- ctxt.Diag("bad opldr12 %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opldr12 %v\n%v", a, p)
return 0
}
-func opstr12(ctxt *obj.Link, a obj.As) uint32 {
- return LD2STR(opldr12(ctxt, a))
+func opstr12(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
+ return LD2STR(opldr12(ctxt, p, a))
}
/*
* load/store register (unscaled immediate) C3.3.12
*/
-func olsr9s(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 {
+func olsr9s(ctxt *obj.Link, p *obj.Prog, o int32, v int32, b int, r int) uint32 {
if v < -256 || v > 255 {
- ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp)
+ ctxt.Diag("offset out of range: %d\n%v", v, p)
}
o |= (v & 0x1FF) << 12
o |= int32(b&31) << 5
return uint32(o)
}
-func opldr9(ctxt *obj.Link, a obj.As) uint32 {
+func opldr9(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case AMOVD:
return LDSTR9S(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */
return LDSTR9S(3, 1, 1)
}
- ctxt.Diag("bad opldr9 %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opldr9 %v\n%v", a, p)
return 0
}
-func opstr9(ctxt *obj.Link, a obj.As) uint32 {
- return LD2STR(opldr9(ctxt, a))
+func opstr9(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
+ return LD2STR(opldr9(ctxt, p, a))
}
-func opldrpp(ctxt *obj.Link, a obj.As) uint32 {
+func opldrpp(ctxt *obj.Link, p *obj.Prog, a obj.As) uint32 {
switch a {
case AMOVD:
return 3<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 /* simm9<<12 | Rn<<5 | Rt */
return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
}
- ctxt.Diag("bad opldr %v\n%v", a, ctxt.Curp)
+ ctxt.Diag("bad opldr %v\n%v", a, p)
return 0
}
/*
* load/store register (extended register)
*/
-func olsxrr(ctxt *obj.Link, as obj.As, rt int, r1 int, r2 int) uint32 {
- ctxt.Diag("need load/store extended register\n%v", ctxt.Curp)
+func olsxrr(ctxt *obj.Link, p *obj.Prog, as obj.As, rt int, r1 int, r2 int) uint32 {
+ ctxt.Diag("need load/store extended register\n%v", p)
return 0xffffffff
}
-func oaddi(ctxt *obj.Link, o1 int32, v int32, r int, rt int) uint32 {
+func oaddi(ctxt *obj.Link, p *obj.Prog, o1 int32, v int32, r int, rt int) uint32 {
if (v & 0xFFF000) != 0 {
if v&0xFFF != 0 {
- ctxt.Diag("%v misuses oaddi", ctxt.Curp)
+ ctxt.Diag("%v misuses oaddi", p)
}
v >>= 12
o1 |= 1 << 22
ctxt.Logf("omovlit add %d (%#x)\n", ctxt.Instoffset, uint64(ctxt.Instoffset))
/* TODO: could be clever, and use general constant builder */
- o1 = int32(opirr(ctxt, AADD))
+ o1 = int32(opirr(ctxt, p, AADD))
v := int32(ctxt.Instoffset)
if v != 0 && (v&0xFFF) == 0 {
case AMOVD:
as1 = AORR
}
- o1 = opirr(ctxt, as1)
+ o1 = opirr(ctxt, p, as1)
o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31)
return o1
}
ctxt.Diag("impossible move wide: %#x\n%v", uint64(a.Offset), p)
}
if as == AMOVD {
- o1 = opirr(ctxt, AMOVN)
+ o1 = opirr(ctxt, p, AMOVN)
} else {
- o1 = opirr(ctxt, AMOVNW)
+ o1 = opirr(ctxt, p, AMOVNW)
}
} else {
if as == AMOVD {
- o1 = opirr(ctxt, AMOVZ)
+ o1 = opirr(ctxt, p, AMOVZ)
} else {
- o1 = opirr(ctxt, AMOVZW)
+ o1 = opirr(ctxt, p, AMOVZW)
}
}
o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
return o1
}
-func opbfm(ctxt *obj.Link, a obj.As, r int, s int, rf int, rt int) uint32 {
+func opbfm(ctxt *obj.Link, p *obj.Prog, a obj.As, r int, s int, rf int, rt int) uint32 {
var c uint32
- o := opirr(ctxt, a)
+ o := opirr(ctxt, p, a)
if (o & (1 << 31)) == 0 {
c = 32
} else {
c = 64
}
if r < 0 || uint32(r) >= c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
+ ctxt.Diag("illegal bit number\n%v", p)
}
o |= (uint32(r) & 0x3F) << 16
if s < 0 || uint32(s) >= c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
+ ctxt.Diag("illegal bit number\n%v", p)
}
o |= (uint32(s) & 0x3F) << 10
o |= (uint32(rf&31) << 5) | uint32(rt&31)
return o
}
-func opextr(ctxt *obj.Link, a obj.As, v int32, rn int, rm int, rt int) uint32 {
+func opextr(ctxt *obj.Link, p *obj.Prog, a obj.As, v int32, rn int, rm int, rt int) uint32 {
var c uint32
- o := opirr(ctxt, a)
+ o := opirr(ctxt, p, a)
if (o & (1 << 31)) != 0 {
c = 63
} else {
c = 31
}
if v < 0 || uint32(v) > c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
+ ctxt.Diag("illegal bit number\n%v", p)
}
o |= uint32(v) << 10
o |= uint32(rn&31) << 5