aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/InstSelectSimple.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/InstSelectSimple.cpp')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 4a04b2910f..4988a0dc4c 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -1502,6 +1502,8 @@ void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
case Intrinsic::frameaddress:
case Intrinsic::memcpy:
case Intrinsic::memset:
+ case Intrinsic::readport:
+ case Intrinsic::writeport:
// We directly implement these intrinsics
break;
default:
@@ -1663,6 +1665,65 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
return;
}
+ case Intrinsic::readport:
+ //
+ // First, determine that the size of the operand falls within the
+ // acceptable range for this architecture.
+ //
+ assert (((CI.getOperand(1)->getType()->getPrimitiveSize()) == 2) &&
+ "llvm.readport operand size is not a 16 bit value!");
+
+ //
+ // Now, move the I/O port address into the DX register and use the IN
+ // instruction to get the input data.
+ //
+ BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(1)));
+ switch (CI.getCalledFunction()->getReturnType()->getPrimitiveSize()) {
+ case 1:
+ BuildMI(BB, X86::IN8, 1);
+ break;
+ case 2:
+ BuildMI(BB, X86::IN16, 1);
+ break;
+ case 4:
+ BuildMI(BB, X86::IN32, 1);
+ break;
+ default:
+ assert (0 && "Cannot do input on this data type");
+ }
+ return;
+
+ case Intrinsic::writeport:
+ //
+ // First, determine that the size of the operand falls within the
+ // acceptable range for this architecture.
+ //
+ assert (((CI.getOperand(1)->getType()->getPrimitiveSize()) == 2) &&
+ "llvm.readport operand size is not a 16 bit value!");
+
+ //
+ // Now, move the I/O port address into the DX register and the value to
+ // write into the AL/AX/EAX register.
+ //
+ BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(1)));
+ switch (CI.getOperand(2)->getType()->getPrimitiveSize()) {
+ case 1:
+ BuildMI(BB, X86::MOV8rr, 1, X86::AL).addReg(getReg(CI.getOperand(2)));
+ BuildMI(BB, X86::OUT8, 1);
+ break;
+ case 2:
+ BuildMI(BB, X86::MOV16rr, 1, X86::AX).addReg(getReg(CI.getOperand(2)));
+ BuildMI(BB, X86::OUT16, 1);
+ break;
+ case 4:
+ BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(getReg(CI.getOperand(2)));
+ BuildMI(BB, X86::OUT32, 1);
+ break;
+ default:
+ assert (0 && "Cannot do input on this data type");
+ }
+ return;
+
default: assert(0 && "Error: unknown intrinsics should have been lowered!");
}
}