Newer
Older
case X86::FpSET_ST0_32:
case X86::FpSET_ST0_64:
// FpSET_ST0_80 is generated by copyRegToReg for both function return
// and inline assembly with the "st" constrain. In the latter case,
// it is possible for ST(0) to be alive after this instruction.
if (!MI->killsRegister(X86::FP0 + Op0)) {
// Duplicate Op0
--StackTop; // "Forget" we have something on the top of stack!
break;
case X86::FpSET_ST1_32:
case X86::FpSET_ST1_64:
case X86::FpSET_ST1_80:
// StackTop can be 1 if a FpSET_ST0_* was before this. Exchange them.
if (StackTop == 1) {
BuildMI(*MBB, I, dl, TII->get(X86::XCH_F)).addReg(X86::ST1);
NumFXCH++;
StackTop = 0;
break;
}
assert(StackTop == 2 && "Stack should have two element on it to return!");
--StackTop; // "Forget" we have something on the top of stack!
break;
case X86::MOV_Fp3232:
case X86::MOV_Fp3264:
case X86::MOV_Fp6432:
case X86::MOV_Fp6464:
case X86::MOV_Fp3280:
case X86::MOV_Fp6480:
case X86::MOV_Fp8032:
case X86::MOV_Fp8064:
case X86::MOV_Fp8080: {
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
const MachineOperand &MO1 = MI->getOperand(1);
unsigned SrcReg = getFPReg(MO1);
const MachineOperand &MO0 = MI->getOperand(0);
// These can be created due to inline asm. Two address pass can introduce
// copies from RFP registers to virtual registers.
if (MO0.getReg() == X86::ST0 && SrcReg == 0) {
assert(MO1.isKill());
// Treat %ST0<def> = MOV_Fp8080 %FP0<kill>
// like FpSET_ST0_80 %FP0<kill>, %ST0<imp-def>
assert((StackTop == 1 || StackTop == 2)
&& "Stack should have one or two element on it to return!");
--StackTop; // "Forget" we have something on the top of stack!
break;
} else if (MO0.getReg() == X86::ST1 && SrcReg == 1) {
assert(MO1.isKill());
// Treat %ST1<def> = MOV_Fp8080 %FP1<kill>
// like FpSET_ST1_80 %FP0<kill>, %ST1<imp-def>
// StackTop can be 1 if a FpSET_ST0_* was before this. Exchange them.
if (StackTop == 1) {
BuildMI(*MBB, I, dl, TII->get(X86::XCH_F)).addReg(X86::ST1);
NumFXCH++;
StackTop = 0;
break;
}
assert(StackTop == 2 && "Stack should have two element on it to return!");
--StackTop; // "Forget" we have something on the top of stack!
break;
}
unsigned DestReg = getFPReg(MO0);
if (MI->killsRegister(X86::FP0+SrcReg)) {
// If the input operand is killed, we can just change the owner of the
// incoming stack slot into the result.
unsigned Slot = getSlot(SrcReg);
assert(Slot < 7 && DestReg < 7 && "FpMOV operands invalid!");
Stack[Slot] = DestReg;
RegMap[DestReg] = Slot;
} else {
// For FMOV we just duplicate the specified value to a new stack slot.
// This could be made better, but would require substantial changes.
duplicateToTop(SrcReg, DestReg, I);
}
Chris Lattner
committed
case TargetInstrInfo::INLINEASM: {
// The inline asm MachineInstr currently only *uses* FP registers for the
// 'f' constraint. These should be turned into the current ST(x) register
// in the machine instr. Also, any kills should be explicitly popped after
// the inline asm.
unsigned Kills[7];
unsigned NumKills = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &Op = MI->getOperand(i);
if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
Chris Lattner
committed
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
continue;
assert(Op.isUse() && "Only handle inline asm uses right now");
unsigned FPReg = getFPReg(Op);
Op.setReg(getSTReg(FPReg));
// If we kill this operand, make sure to pop it from the stack after the
// asm. We just remember it for now, and pop them all off at the end in
// a batch.
if (Op.isKill())
Kills[NumKills++] = FPReg;
}
// If this asm kills any FP registers (is the last use of them) we must
// explicitly emit pop instructions for them. Do this now after the asm has
// executed so that the ST(x) numbers are not off (which would happen if we
// did this inline with operand rewriting).
//
// Note: this might be a non-optimal pop sequence. We might be able to do
// better by trying to pop in stack order or something.
MachineBasicBlock::iterator InsertPt = MI;
while (NumKills)
freeStackSlotAfter(InsertPt, Kills[--NumKills]);
// Don't delete the inline asm!
return;
}
case X86::RET:
case X86::RETI:
// If RET has an FP register use operand, pass the first one in ST(0) and
// the second one in ST(1).
if (isStackEmpty()) return; // Quick check to see if any are possible.
// Find the register operands.
unsigned FirstFPRegOp = ~0U, SecondFPRegOp = ~0U;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &Op = MI->getOperand(i);
if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
continue;
// FP Register uses must be kills unless there are two uses of the same
// register, in which case only one will be a kill.
assert(Op.isUse() &&
(Op.isKill() || // Marked kill.
getFPReg(Op) == FirstFPRegOp || // Second instance.
MI->killsRegister(Op.getReg())) && // Later use is marked kill.
"Ret only defs operands, and values aren't live beyond it");
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
if (FirstFPRegOp == ~0U)
FirstFPRegOp = getFPReg(Op);
else {
assert(SecondFPRegOp == ~0U && "More than two fp operands!");
SecondFPRegOp = getFPReg(Op);
}
// Remove the operand so that later passes don't see it.
MI->RemoveOperand(i);
--i, --e;
}
// There are only four possibilities here:
// 1) we are returning a single FP value. In this case, it has to be in
// ST(0) already, so just declare success by removing the value from the
// FP Stack.
if (SecondFPRegOp == ~0U) {
// Assert that the top of stack contains the right FP register.
assert(StackTop == 1 && FirstFPRegOp == getStackEntry(0) &&
"Top of stack not the right register for RET!");
// Ok, everything is good, mark the value as not being on the stack
// anymore so that our assertion about the stack being empty at end of
// block doesn't fire.
StackTop = 0;
return;
}
// Otherwise, we are returning two values:
// 2) If returning the same value for both, we only have one thing in the FP
// stack. Consider: RET FP1, FP1
if (StackTop == 1) {
assert(FirstFPRegOp == SecondFPRegOp && FirstFPRegOp == getStackEntry(0)&&
"Stack misconfiguration for RET!");
// Duplicate the TOS so that we return it twice. Just pick some other FPx
// register to hold it.
unsigned NewReg = (FirstFPRegOp+1)%7;
duplicateToTop(FirstFPRegOp, NewReg, MI);
FirstFPRegOp = NewReg;
}
/// Okay we know we have two different FPx operands now:
assert(StackTop == 2 && "Must have two values live!");
/// 3) If SecondFPRegOp is currently in ST(0) and FirstFPRegOp is currently
/// in ST(1). In this case, emit an fxch.
if (getStackEntry(0) == SecondFPRegOp) {
assert(getStackEntry(1) == FirstFPRegOp && "Unknown regs live");
moveToTop(FirstFPRegOp, MI);
}
/// 4) Finally, FirstFPRegOp must be in ST(0) and SecondFPRegOp must be in
/// ST(1). Just remove both from our understanding of the stack and return.
assert(getStackEntry(0) == FirstFPRegOp && "Unknown regs live");
assert(getStackEntry(1) == SecondFPRegOp && "Unknown regs live");
StackTop = 0;
return;
I = MBB->erase(I); // Remove the pseudo instruction
--I;