예제 #1
0
        public override void ExitRel1(ssuplParser.Rel1Context context)
        {
            //rel    : sum RELOP sum
            string mnemonic;

            switch (context.RELOP().GetText())
            {
            case ">=": mnemonic = "setge"; break;

            case "<=": mnemonic = "setle"; break;

            case ">": mnemonic = "setg"; break;

            case "<": mnemonic = "setl"; break;

            case "==": mnemonic = "sete"; break;

            case "!=": mnemonic = "setne"; break;

            default: throw new Exception();
            }
            code.Put(context,
                     code.Get(context.sum()[0]),
                     code.Get(context.sum()[1]),
                     "pop rbx",            //second operand
                     "pop rax",            //first operand
                     "cmp rax,rbx",        //do the compare
                     $"{mnemonic} al",     //set low byte of rax (0 or 1)
                     "movzx qword rax,al", //zero extend
                     "push rax"
                     );
        }
예제 #2
0
        public override void ExitRel1(ssuplParser.Rel1Context context)
        {
            //rel    : sum RELOP sum
            if (type(context.sum()[0]) != type(context.sum()[1]))
            {
                throw new Exception("Type mismatch");
            }
            typeAttr.Put(context, VarType.INT);
            string mnemonic;
            int    op;

            switch (context.RELOP().GetText())
            {
            case ">=": mnemonic = "setge"; op = 5; break;

            case "<=": mnemonic = "setle"; op = 2; break;

            case ">": mnemonic = "setg"; op = 6; break;

            case "<": mnemonic = "setl"; op = 1; break;

            case "==": mnemonic = "sete"; op = 0; break;

            case "!=": mnemonic = "setne"; op = 4; break;

            default: throw new Exception();
            }
            switch (type(context.sum()[0]))
            {
            case VarType.INT:
                code.Put(context,
                         code.Get(context.sum()[0]),
                         code.Get(context.sum()[1]),
                         "pop rbx",            //second operand
                         "pop rax",            //first operand
                         "cmp rax,rbx",        //do the compare
                         $"{mnemonic} al",     //set low byte of rax (0 or 1)
                         "movzx qword rax,al", //zero extend
                         "push rax"
                         );
                break;

            case VarType.DOUBLE:
                code.Put(context,
                         code.Get(context.sum()[0]),
                         code.Get(context.sum()[1]),
                         "movq xmm1, [rsp]", //pop value...
                         "add rsp,8",        //...from second operand
                         "movq xmm0, [rsp]", //pop value...
                         "add rsp,8",        //...from first operand
                         $"cmpsd xmm0, xmm1, {op}",
                         "movq rax,xmm0",    //need to convert to 0 or 1
                         "and rax,1",
                         "push rax"
                         );
                break;
            }
        }