func ginscmp(op gc.Op, t *gc.Type, n1, n2 *gc.Node, likely int) *obj.Prog { if t.IsInteger() && n1.Op == gc.OLITERAL && n2.Op != gc.OLITERAL { // Reverse comparison to place constant last. op = gc.Brrev(op) n1, n2 = n2, n1 } var r1, r2, g1, g2 gc.Node gc.Regalloc(&r1, t, n1) gc.Regalloc(&g1, n1.Type, &r1) gc.Cgen(n1, &g1) gmove(&g1, &r1) if t.IsInteger() && gc.Isconst(n2, gc.CTINT) { ginscon2(optoas(gc.OCMP, t), &r1, n2.Int64()) } else { gc.Regalloc(&r2, t, n2) gc.Regalloc(&g2, n1.Type, &r2) gc.Cgen(n2, &g2) gmove(&g2, &r2) gcmp(optoas(gc.OCMP, t), &r1, &r2) gc.Regfree(&g2) gc.Regfree(&r2) } gc.Regfree(&g1) gc.Regfree(&r1) return gc.Gbranch(optoas(op, t), nil, likely) }
func ginscmp(op gc.Op, t *gc.Type, n1, n2 *gc.Node, likely int) *obj.Prog { if t.IsInteger() && n1.Op == gc.OLITERAL && n1.Int64() == 0 && n2.Op != gc.OLITERAL { op = gc.Brrev(op) n1, n2 = n2, n1 } var r1, r2, g1, g2 gc.Node gc.Regalloc(&r1, t, n1) gc.Regalloc(&g1, n1.Type, &r1) gc.Cgen(n1, &g1) gmove(&g1, &r1) if t.IsInteger() && n2.Op == gc.OLITERAL && n2.Int64() == 0 { gins(arm.ACMP, &r1, n2) } else { gc.Regalloc(&r2, t, n2) gc.Regalloc(&g2, n1.Type, &r2) gc.Cgen(n2, &g2) gmove(&g2, &r2) gins(optoas(gc.OCMP, t), &r1, &r2) gc.Regfree(&g2) gc.Regfree(&r2) } gc.Regfree(&g1) gc.Regfree(&r1) return gc.Gbranch(optoas(op, t), nil, likely) }
func ginscmp(op gc.Op, t *gc.Type, n1, n2 *gc.Node, likely int) *obj.Prog { if t.IsInteger() || t.Etype == gc.Tptr { if (n1.Op == gc.OLITERAL || n1.Op == gc.OADDR && n1.Left.Op == gc.ONAME) && n2.Op != gc.OLITERAL { // Reverse comparison to place constant (including address constant) last. op = gc.Brrev(op) n1, n2 = n2, n1 } } // General case. var r1, r2, g1, g2 gc.Node // A special case to make write barriers more efficient. // Comparing the first field of a named struct can be done directly. base := n1 if n1.Op == gc.ODOT && n1.Left.Type.IsStruct() && n1.Left.Type.Field(0).Sym == n1.Sym { base = n1.Left } if base.Op == gc.ONAME && base.Class != gc.PAUTOHEAP || n1.Op == gc.OINDREG { r1 = *n1 } else { gc.Regalloc(&r1, t, n1) gc.Regalloc(&g1, n1.Type, &r1) gc.Cgen(n1, &g1) gmove(&g1, &r1) } if n2.Op == gc.OLITERAL && t.IsInteger() || n2.Op == gc.OADDR && n2.Left.Op == gc.ONAME && n2.Left.Class == gc.PEXTERN { r2 = *n2 } else { gc.Regalloc(&r2, t, n2) gc.Regalloc(&g2, n1.Type, &r2) gc.Cgen(n2, &g2) gmove(&g2, &r2) } gins(optoas(gc.OCMP, t), &r1, &r2) if r1.Op == gc.OREGISTER { gc.Regfree(&g1) gc.Regfree(&r1) } if r2.Op == gc.OREGISTER { gc.Regfree(&g2) gc.Regfree(&r2) } return gc.Gbranch(optoas(op, t), nil, likely) }
func ginscmp(op gc.Op, t *gc.Type, n1, n2 *gc.Node, likely int) *obj.Prog { if !t.IsFloat() && (op == gc.OLT || op == gc.OGE) { // swap nodes to fit SGT instruction n1, n2 = n2, n1 } if t.IsFloat() && (op == gc.OLT || op == gc.OLE) { // swap nodes to fit CMPGT, CMPGE instructions and reverse relation n1, n2 = n2, n1 if op == gc.OLT { op = gc.OGT } else { op = gc.OGE } } var r1, r2, g1, g2 gc.Node gc.Regalloc(&r1, t, n1) gc.Regalloc(&g1, n1.Type, &r1) gc.Cgen(n1, &g1) gmove(&g1, &r1) gc.Regalloc(&r2, t, n2) gc.Regalloc(&g2, n1.Type, &r2) gc.Cgen(n2, &g2) gmove(&g2, &r2) var p *obj.Prog var ntmp gc.Node gc.Nodreg(&ntmp, gc.Types[gc.TINT], mips.REGTMP) switch gc.Simtype[t.Etype] { case gc.TINT8, gc.TINT16, gc.TINT32, gc.TINT64: if op == gc.OEQ || op == gc.ONE { p = ginsbranch(optoas(op, t), nil, &r1, &r2, likely) } else { gins3(mips.ASGT, &r1, &r2, &ntmp) p = ginsbranch(optoas(op, t), nil, &ntmp, nil, likely) } case gc.TBOOL, gc.TUINT8, gc.TUINT16, gc.TUINT32, gc.TUINT64, gc.TPTR32, gc.TPTR64: if op == gc.OEQ || op == gc.ONE { p = ginsbranch(optoas(op, t), nil, &r1, &r2, likely) } else { gins3(mips.ASGTU, &r1, &r2, &ntmp) p = ginsbranch(optoas(op, t), nil, &ntmp, nil, likely) } case gc.TFLOAT32: switch op { default: gc.Fatalf("ginscmp: no entry for op=%s type=%v", op, t) case gc.OEQ, gc.ONE: gins3(mips.ACMPEQF, &r1, &r2, nil) case gc.OGE: gins3(mips.ACMPGEF, &r1, &r2, nil) case gc.OGT: gins3(mips.ACMPGTF, &r1, &r2, nil) } p = gc.Gbranch(optoas(op, t), nil, likely) case gc.TFLOAT64: switch op { default: gc.Fatalf("ginscmp: no entry for op=%s type=%v", op, t) case gc.OEQ, gc.ONE: gins3(mips.ACMPEQD, &r1, &r2, nil) case gc.OGE: gins3(mips.ACMPGED, &r1, &r2, nil) case gc.OGT: gins3(mips.ACMPGTD, &r1, &r2, nil) } p = gc.Gbranch(optoas(op, t), nil, likely) } gc.Regfree(&g2) gc.Regfree(&r2) gc.Regfree(&g1) gc.Regfree(&r1) return p }