OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 // test t1, 0x20 | 933 // test t1, 0x20 |
934 // je L1 | 934 // je L1 |
935 // use(t3) | 935 // use(t3) |
936 // t3 = t2 | 936 // t3 = t2 |
937 // t2 = 0 | 937 // t2 = 0 |
938 // L1: | 938 // L1: |
939 // a.lo = t2 | 939 // a.lo = t2 |
940 // a.hi = t3 | 940 // a.hi = t3 |
941 Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL; | 941 Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL; |
942 Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20); | 942 Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20); |
943 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 943 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
944 InstX8632Label *Label = InstX8632Label::create(Func, this); | 944 InstX8632Label *Label = InstX8632Label::create(Func, this); |
945 _mov(T_1, Src1Lo, Reg_ecx); | 945 _mov(T_1, Src1Lo, Reg_ecx); |
946 _mov(T_2, Src0Lo); | 946 _mov(T_2, Src0Lo); |
947 _mov(T_3, Src0Hi); | 947 _mov(T_3, Src0Hi); |
948 _shld(T_3, T_2, T_1); | 948 _shld(T_3, T_2, T_1); |
949 _shl(T_2, T_1); | 949 _shl(T_2, T_1); |
950 _test(T_1, BitTest); | 950 _test(T_1, BitTest); |
951 _br(InstX8632Br::Br_e, Label); | 951 _br(InstX8632Br::Br_e, Label); |
952 // Because of the intra-block control flow, we need to fake a use | 952 // Because of the intra-block control flow, we need to fake a use |
953 // of T_3 to prevent its earlier definition from being dead-code | 953 // of T_3 to prevent its earlier definition from being dead-code |
(...skipping 15 matching lines...) Expand all Loading... |
969 // test t1, 0x20 | 969 // test t1, 0x20 |
970 // je L1 | 970 // je L1 |
971 // use(t2) | 971 // use(t2) |
972 // t2 = t3 | 972 // t2 = t3 |
973 // t3 = 0 | 973 // t3 = 0 |
974 // L1: | 974 // L1: |
975 // a.lo = t2 | 975 // a.lo = t2 |
976 // a.hi = t3 | 976 // a.hi = t3 |
977 Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL; | 977 Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL; |
978 Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20); | 978 Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20); |
979 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 979 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
980 InstX8632Label *Label = InstX8632Label::create(Func, this); | 980 InstX8632Label *Label = InstX8632Label::create(Func, this); |
981 _mov(T_1, Src1Lo, Reg_ecx); | 981 _mov(T_1, Src1Lo, Reg_ecx); |
982 _mov(T_2, Src0Lo); | 982 _mov(T_2, Src0Lo); |
983 _mov(T_3, Src0Hi); | 983 _mov(T_3, Src0Hi); |
984 _shrd(T_2, T_3, T_1); | 984 _shrd(T_2, T_3, T_1); |
985 _shr(T_3, T_1); | 985 _shr(T_3, T_1); |
986 _test(T_1, BitTest); | 986 _test(T_1, BitTest); |
987 _br(InstX8632Br::Br_e, Label); | 987 _br(InstX8632Br::Br_e, Label); |
988 // Because of the intra-block control flow, we need to fake a use | 988 // Because of the intra-block control flow, we need to fake a use |
989 // of T_3 to prevent its earlier definition from being dead-code | 989 // of T_3 to prevent its earlier definition from being dead-code |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 Src1 = legalizeToVar(Src1, false, Reg_ecx); | 1134 Src1 = legalizeToVar(Src1, false, Reg_ecx); |
1135 _sar(T, Src1); | 1135 _sar(T, Src1); |
1136 _mov(Dest, T); | 1136 _mov(Dest, T); |
1137 break; | 1137 break; |
1138 case InstArithmetic::Udiv: | 1138 case InstArithmetic::Udiv: |
1139 // div and idiv are the few arithmetic operators that do not allow | 1139 // div and idiv are the few arithmetic operators that do not allow |
1140 // immediates as the operand. | 1140 // immediates as the operand. |
1141 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1141 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1142 if (Dest->getType() == IceType_i8) { | 1142 if (Dest->getType() == IceType_i8) { |
1143 Variable *T_ah = NULL; | 1143 Variable *T_ah = NULL; |
1144 Constant *Zero = Ctx->getConstantInt(IceType_i8, 0); | 1144 Constant *Zero = Ctx->getConstantZero(IceType_i8); |
1145 _mov(T, Src0, Reg_eax); | 1145 _mov(T, Src0, Reg_eax); |
1146 _mov(T_ah, Zero, Reg_ah); | 1146 _mov(T_ah, Zero, Reg_ah); |
1147 _div(T, Src1, T_ah); | 1147 _div(T, Src1, T_ah); |
1148 _mov(Dest, T); | 1148 _mov(Dest, T); |
1149 } else { | 1149 } else { |
1150 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 1150 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1151 _mov(T, Src0, Reg_eax); | 1151 _mov(T, Src0, Reg_eax); |
1152 _mov(T_edx, Zero, Reg_edx); | 1152 _mov(T_edx, Zero, Reg_edx); |
1153 _div(T, Src1, T_edx); | 1153 _div(T, Src1, T_edx); |
1154 _mov(Dest, T); | 1154 _mov(Dest, T); |
1155 } | 1155 } |
1156 break; | 1156 break; |
1157 case InstArithmetic::Sdiv: | 1157 case InstArithmetic::Sdiv: |
1158 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1158 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1159 T_edx = makeReg(IceType_i32, Reg_edx); | 1159 T_edx = makeReg(IceType_i32, Reg_edx); |
1160 _mov(T, Src0, Reg_eax); | 1160 _mov(T, Src0, Reg_eax); |
1161 _cdq(T_edx, T); | 1161 _cdq(T_edx, T); |
1162 _idiv(T, Src1, T_edx); | 1162 _idiv(T, Src1, T_edx); |
1163 _mov(Dest, T); | 1163 _mov(Dest, T); |
1164 break; | 1164 break; |
1165 case InstArithmetic::Urem: | 1165 case InstArithmetic::Urem: |
1166 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1166 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1167 if (Dest->getType() == IceType_i8) { | 1167 if (Dest->getType() == IceType_i8) { |
1168 Variable *T_ah = NULL; | 1168 Variable *T_ah = NULL; |
1169 Constant *Zero = Ctx->getConstantInt(IceType_i8, 0); | 1169 Constant *Zero = Ctx->getConstantZero(IceType_i8); |
1170 _mov(T, Src0, Reg_eax); | 1170 _mov(T, Src0, Reg_eax); |
1171 _mov(T_ah, Zero, Reg_ah); | 1171 _mov(T_ah, Zero, Reg_ah); |
1172 _div(T_ah, Src1, T); | 1172 _div(T_ah, Src1, T); |
1173 _mov(Dest, T_ah); | 1173 _mov(Dest, T_ah); |
1174 } else { | 1174 } else { |
1175 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 1175 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1176 _mov(T_edx, Zero, Reg_edx); | 1176 _mov(T_edx, Zero, Reg_edx); |
1177 _mov(T, Src0, Reg_eax); | 1177 _mov(T, Src0, Reg_eax); |
1178 _div(T_edx, Src1, T); | 1178 _div(T_edx, Src1, T); |
1179 _mov(Dest, T_edx); | 1179 _mov(Dest, T_edx); |
1180 } | 1180 } |
1181 break; | 1181 break; |
1182 case InstArithmetic::Srem: | 1182 case InstArithmetic::Srem: |
1183 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1183 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1184 T_edx = makeReg(IceType_i32, Reg_edx); | 1184 T_edx = makeReg(IceType_i32, Reg_edx); |
1185 _mov(T, Src0, Reg_eax); | 1185 _mov(T, Src0, Reg_eax); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 Operand *RI = legalize(Src0, Legal_Reg | Legal_Imm, AllowOverlap); | 1241 Operand *RI = legalize(Src0, Legal_Reg | Legal_Imm, AllowOverlap); |
1242 _mov(Dest, RI); | 1242 _mov(Dest, RI); |
1243 } | 1243 } |
1244 } | 1244 } |
1245 | 1245 |
1246 void TargetX8632::lowerBr(const InstBr *Inst) { | 1246 void TargetX8632::lowerBr(const InstBr *Inst) { |
1247 if (Inst->isUnconditional()) { | 1247 if (Inst->isUnconditional()) { |
1248 _br(Inst->getTargetUnconditional()); | 1248 _br(Inst->getTargetUnconditional()); |
1249 } else { | 1249 } else { |
1250 Operand *Src0 = legalize(Inst->getCondition()); | 1250 Operand *Src0 = legalize(Inst->getCondition()); |
1251 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 1251 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1252 _cmp(Src0, Zero); | 1252 _cmp(Src0, Zero); |
1253 _br(InstX8632Br::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse()); | 1253 _br(InstX8632Br::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse()); |
1254 } | 1254 } |
1255 } | 1255 } |
1256 | 1256 |
1257 void TargetX8632::lowerCall(const InstCall *Instr) { | 1257 void TargetX8632::lowerCall(const InstCall *Instr) { |
1258 // Generate a sequence of push instructions, pushing right to left, | 1258 // Generate a sequence of push instructions, pushing right to left, |
1259 // keeping track of stack offsets in case a push involves a stack | 1259 // keeping track of stack offsets in case a push involves a stack |
1260 // operand and we are using an esp-based frame. | 1260 // operand and we are using an esp-based frame. |
1261 uint32_t StackOffset = 0; | 1261 uint32_t StackOffset = 0; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 // also copy to the high operand of a 64-bit variable. | 1404 // also copy to the high operand of a 64-bit variable. |
1405 // t1 = movsx src; dst = t1 | 1405 // t1 = movsx src; dst = t1 |
1406 Variable *T = makeReg(Dest->getType()); | 1406 Variable *T = makeReg(Dest->getType()); |
1407 _movsx(T, Src0RM); | 1407 _movsx(T, Src0RM); |
1408 _mov(Dest, T); | 1408 _mov(Dest, T); |
1409 } | 1409 } |
1410 break; | 1410 break; |
1411 case InstCast::Zext: | 1411 case InstCast::Zext: |
1412 if (Dest->getType() == IceType_i64) { | 1412 if (Dest->getType() == IceType_i64) { |
1413 // t1=movzx src; dst.lo=t1; dst.hi=0 | 1413 // t1=movzx src; dst.lo=t1; dst.hi=0 |
1414 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 1414 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1415 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1415 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
1416 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1416 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
1417 Variable *Tmp = makeReg(DestLo->getType()); | 1417 Variable *Tmp = makeReg(DestLo->getType()); |
1418 if (Src0RM->getType() == IceType_i32) | 1418 if (Src0RM->getType() == IceType_i32) |
1419 _mov(Tmp, Src0RM); | 1419 _mov(Tmp, Src0RM); |
1420 else | 1420 else |
1421 _movzx(Tmp, Src0RM); | 1421 _movzx(Tmp, Src0RM); |
1422 _mov(DestLo, Tmp); | 1422 _mov(DestLo, Tmp); |
1423 _mov(DestHi, Zero); | 1423 _mov(DestHi, Zero); |
1424 } else if (Src0RM->getType() == IceType_i1) { | 1424 } else if (Src0RM->getType() == IceType_i1) { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), | 1720 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), |
1721 NextBr->getTargetFalse()); | 1721 NextBr->getTargetFalse()); |
1722 // Skip over the following branch instruction. | 1722 // Skip over the following branch instruction. |
1723 NextBr->setDeleted(); | 1723 NextBr->setDeleted(); |
1724 Context.advanceNext(); | 1724 Context.advanceNext(); |
1725 return; | 1725 return; |
1726 } | 1726 } |
1727 } | 1727 } |
1728 | 1728 |
1729 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: | 1729 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: |
1730 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 1730 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1731 Constant *One = Ctx->getConstantInt(IceType_i32, 1); | 1731 Constant *One = Ctx->getConstantInt(IceType_i32, 1); |
1732 if (Src0->getType() == IceType_i64) { | 1732 if (Src0->getType() == IceType_i64) { |
1733 InstIcmp::ICond Condition = Inst->getCondition(); | 1733 InstIcmp::ICond Condition = Inst->getCondition(); |
1734 size_t Index = static_cast<size_t>(Condition); | 1734 size_t Index = static_cast<size_t>(Condition); |
1735 assert(Index < TableIcmp64Size); | 1735 assert(Index < TableIcmp64Size); |
1736 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); | 1736 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); |
1737 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); | 1737 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); |
1738 if (Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) { | 1738 if (Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) { |
1739 InstX8632Label *Label = InstX8632Label::create(Func, this); | 1739 InstX8632Label *Label = InstX8632Label::create(Func, this); |
1740 _mov(Dest, (Condition == InstIcmp::Eq ? Zero : One)); | 1740 _mov(Dest, (Condition == InstIcmp::Eq ? Zero : One)); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp); | 2007 Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp); |
2008 Context.insert(InstFakeUse::create(Func, esp)); | 2008 Context.insert(InstFakeUse::create(Func, esp)); |
2009 } | 2009 } |
2010 | 2010 |
2011 void TargetX8632::lowerSelect(const InstSelect *Inst) { | 2011 void TargetX8632::lowerSelect(const InstSelect *Inst) { |
2012 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: | 2012 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: |
2013 Variable *Dest = Inst->getDest(); | 2013 Variable *Dest = Inst->getDest(); |
2014 Operand *SrcT = Inst->getTrueOperand(); | 2014 Operand *SrcT = Inst->getTrueOperand(); |
2015 Operand *SrcF = Inst->getFalseOperand(); | 2015 Operand *SrcF = Inst->getFalseOperand(); |
2016 Operand *Condition = legalize(Inst->getCondition()); | 2016 Operand *Condition = legalize(Inst->getCondition()); |
2017 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | 2017 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
2018 InstX8632Label *Label = InstX8632Label::create(Func, this); | 2018 InstX8632Label *Label = InstX8632Label::create(Func, this); |
2019 | 2019 |
2020 if (Dest->getType() == IceType_i64) { | 2020 if (Dest->getType() == IceType_i64) { |
2021 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2021 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2022 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2022 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2023 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true); | 2023 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true); |
2024 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true); | 2024 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true); |
2025 _cmp(Condition, Zero); | 2025 _cmp(Condition, Zero); |
2026 _mov(DestLo, SrcLoRI); | 2026 _mov(DestLo, SrcLoRI); |
2027 _mov(DestHi, SrcHiRI); | 2027 _mov(DestHi, SrcHiRI); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2283 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 2283 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
2284 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 2284 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
2285 } | 2285 } |
2286 | 2286 |
2287 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 2287 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
2288 Ostream &Str = Ctx->getStrEmit(); | 2288 Ostream &Str = Ctx->getStrEmit(); |
2289 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 2289 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
2290 } | 2290 } |
2291 | 2291 |
2292 } // end of namespace Ice | 2292 } // end of namespace Ice |
OLD | NEW |