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 }