BLTU 0(PC) // a7540000
BLEU 0(PC) // a7d40000
+ BRCT R1, 0(PC) // a7160000
+ BRCTG R2, 0(PC) // a7270000
+
CMPBNE R1, R2, 0(PC) // ec1200007064
CMPBEQ R3, R4, 0(PC) // ec3400008064
CMPBLT R5, R6, 0(PC) // ec5600004064
// Generate a loop of large clears.
if cnt > clearLoopCutoff {
- n := cnt - (cnt % 256)
- end := int16(s390x.REGRT2)
- p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off+n, obj.TYPE_REG, end, 0)
- p.Reg = reg
+ ireg := int16(s390x.REGRT2) // register holds number of remaining loop iterations
+ p = pp.Appendpp(p, s390x.AMOVD, obj.TYPE_CONST, 0, cnt/256, obj.TYPE_REG, ireg, 0)
p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off)
pl := p
p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
- p = pp.Appendpp(p, s390x.ACMP, obj.TYPE_REG, reg, 0, obj.TYPE_REG, end, 0)
- p = pp.Appendpp(p, s390x.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+ p = pp.Appendpp(p, s390x.ABRCTG, obj.TYPE_REG, ireg, 0, obj.TYPE_BRANCH, 0, 0)
gc.Patch(p, pl)
-
- cnt -= n
+ cnt = cnt % 256
}
// Generate remaining clear instructions without a loop.
{i: 90, as: ACLGIJ, a1: C_SCON, a2: C_REG, a3: C_ADDCON, a6: C_SBRA},
{i: 90, as: ACMPUBEQ, a1: C_REG, a3: C_ANDCON, a6: C_SBRA},
+ // branch on count
+ {i: 41, as: ABRCT, a1: C_REG, a6: C_SBRA},
+ {i: 41, as: ABRCTG, a1: C_REG, a6: C_SBRA},
+
// move on condition
{i: 17, as: AMOVDEQ, a1: C_REG, a6: C_REG},
*asm = append(*asm, uint8(wd))
}
+ case 41: // branch on count
+ r1 := p.From.Reg
+ ri2 := (p.Pcond.Pc - p.Pc) >> 1
+ if int64(int16(ri2)) != ri2 {
+ c.ctxt.Diag("branch target too far away")
+ }
+ var opcode uint32
+ switch p.As {
+ case ABRCT:
+ opcode = op_BRCT
+ case ABRCTG:
+ opcode = op_BRCTG
+ }
+ zRI(opcode, uint32(r1), uint32(ri2), asm)
+
case 47: // negate [reg] reg
r := p.From.Reg
if r == 0 {