diff options
Diffstat (limited to 'lib/Target/X86/X86ISelSimple.cpp')
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 4a04b2910f..4988a0dc4c 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.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!"); } } |