mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +00:00
remove the read/write port/io intrinsics.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26479 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
472c0ebea4
commit
41edaa0529
@ -143,13 +143,6 @@
|
|||||||
<li><a href="#i_readcyclecounter"><tt>llvm.readcyclecounter</tt>' Intrinsic</a></li>
|
<li><a href="#i_readcyclecounter"><tt>llvm.readcyclecounter</tt>' Intrinsic</a></li>
|
||||||
</ol>
|
</ol>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#int_os">Operating System Intrinsics</a>
|
|
||||||
<ol>
|
|
||||||
<li><a href="#i_readport">'<tt>llvm.readport</tt>' Intrinsic</a></li>
|
|
||||||
<li><a href="#i_writeport">'<tt>llvm.writeport</tt>' Intrinsic</a></li>
|
|
||||||
<li><a href="#i_readio">'<tt>llvm.readio</tt>' Intrinsic</a></li>
|
|
||||||
<li><a href="#i_writeio">'<tt>llvm.writeio</tt>' Intrinsic</a></li>
|
|
||||||
</ol>
|
|
||||||
<li><a href="#int_libc">Standard C Library Intrinsics</a>
|
<li><a href="#int_libc">Standard C Library Intrinsics</a>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="#i_memcpy">'<tt>llvm.memcpy.*</tt>' Intrinsic</a></li>
|
<li><a href="#i_memcpy">'<tt>llvm.memcpy.*</tt>' Intrinsic</a></li>
|
||||||
@ -3266,199 +3259,6 @@ system wide value. On backends without support, this is lowered to a constant 0
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
|
||||||
<div class="doc_subsection">
|
|
||||||
<a name="int_os">Operating System Intrinsics</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="doc_text">
|
|
||||||
<p>
|
|
||||||
These intrinsics are provided by LLVM to support the implementation of
|
|
||||||
operating system level code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
|
||||||
<div class="doc_subsubsection">
|
|
||||||
<a name="i_readport">'<tt>llvm.readport</tt>' Intrinsic</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="doc_text">
|
|
||||||
|
|
||||||
<h5>Syntax:</h5>
|
|
||||||
<pre>
|
|
||||||
declare <integer type> %llvm.readport (<integer type> <address>)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h5>Overview:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.readport</tt>' intrinsic reads data from the specified hardware
|
|
||||||
I/O port.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Arguments:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The argument to this intrinsic indicates the hardware I/O address from which
|
|
||||||
to read the data. The address is in the hardware I/O address namespace (as
|
|
||||||
opposed to being a memory location for memory mapped I/O).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Semantics:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.readport</tt>' intrinsic reads data from the hardware I/O port
|
|
||||||
specified by <i>address</i> and returns the value. The address and return
|
|
||||||
value must be integers, but the size is dependent upon the platform upon which
|
|
||||||
the program is code generated. For example, on x86, the address must be an
|
|
||||||
unsigned 16-bit value, and the return value must be 8, 16, or 32 bits.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
|
||||||
<div class="doc_subsubsection">
|
|
||||||
<a name="i_writeport">'<tt>llvm.writeport</tt>' Intrinsic</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="doc_text">
|
|
||||||
|
|
||||||
<h5>Syntax:</h5>
|
|
||||||
<pre>
|
|
||||||
call void (<integer type>, <integer type>)*
|
|
||||||
%llvm.writeport (<integer type> <value>,
|
|
||||||
<integer type> <address>)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h5>Overview:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.writeport</tt>' intrinsic writes data to the specified hardware
|
|
||||||
I/O port.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Arguments:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The first argument is the value to write to the I/O port.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The second argument indicates the hardware I/O address to which data should be
|
|
||||||
written. The address is in the hardware I/O address namespace (as opposed to
|
|
||||||
being a memory location for memory mapped I/O).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Semantics:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.writeport</tt>' intrinsic writes <i>value</i> to the I/O port
|
|
||||||
specified by <i>address</i>. The address and value must be integers, but the
|
|
||||||
size is dependent upon the platform upon which the program is code generated.
|
|
||||||
For example, on x86, the address must be an unsigned 16-bit value, and the
|
|
||||||
value written must be 8, 16, or 32 bits in length.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
|
||||||
<div class="doc_subsubsection">
|
|
||||||
<a name="i_readio">'<tt>llvm.readio</tt>' Intrinsic</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="doc_text">
|
|
||||||
|
|
||||||
<h5>Syntax:</h5>
|
|
||||||
<pre>
|
|
||||||
declare <result> %llvm.readio (<ty> * <pointer>)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h5>Overview:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.readio</tt>' intrinsic reads data from a memory mapped I/O
|
|
||||||
address.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Arguments:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The argument to this intrinsic is a pointer indicating the memory address from
|
|
||||||
which to read the data. The data must be a
|
|
||||||
<a href="#t_firstclass">first class</a> type.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Semantics:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.readio</tt>' intrinsic reads data from a memory mapped I/O
|
|
||||||
location specified by <i>pointer</i> and returns the value. The argument must
|
|
||||||
be a pointer, and the return value must be a
|
|
||||||
<a href="#t_firstclass">first class</a> type. However, certain architectures
|
|
||||||
may not support I/O on all first class types. For example, 32-bit processors
|
|
||||||
may only support I/O on data types that are 32 bits or less.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This intrinsic enforces an in-order memory model for llvm.readio and
|
|
||||||
llvm.writeio calls on machines that use dynamic scheduling. Dynamically
|
|
||||||
scheduled processors may execute loads and stores out of order, re-ordering at
|
|
||||||
run time accesses to memory mapped I/O registers. Using these intrinsics
|
|
||||||
ensures that accesses to memory mapped I/O registers occur in program order.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
|
||||||
<div class="doc_subsubsection">
|
|
||||||
<a name="i_writeio">'<tt>llvm.writeio</tt>' Intrinsic</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="doc_text">
|
|
||||||
|
|
||||||
<h5>Syntax:</h5>
|
|
||||||
<pre>
|
|
||||||
declare void %llvm.writeio (<ty1> <value>, <ty2> * <pointer>)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h5>Overview:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.writeio</tt>' intrinsic writes data to the specified memory
|
|
||||||
mapped I/O address.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Arguments:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The first argument is the value to write to the memory mapped I/O location.
|
|
||||||
The second argument is a pointer indicating the memory address to which the
|
|
||||||
data should be written.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Semantics:</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The '<tt>llvm.writeio</tt>' intrinsic writes <i>value</i> to the memory mapped
|
|
||||||
I/O address specified by <i>pointer</i>. The value must be a
|
|
||||||
<a href="#t_firstclass">first class</a> type. However, certain architectures
|
|
||||||
may not support I/O on all first class types. For example, 32-bit processors
|
|
||||||
may only support I/O on data types that are 32 bits or less.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This intrinsic enforces an in-order memory model for llvm.readio and
|
|
||||||
llvm.writeio calls on machines that use dynamic scheduling. Dynamically
|
|
||||||
scheduled processors may execute loads and stores out of order, re-ordering at
|
|
||||||
run time accesses to memory mapped I/O registers. Using these intrinsics
|
|
||||||
ensures that accesses to memory mapped I/O registers occur in program order.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
<div class="doc_subsection">
|
<div class="doc_subsection">
|
||||||
<a name="int_libc">Standard C Library Intrinsics</a>
|
<a name="int_libc">Standard C Library Intrinsics</a>
|
||||||
|
@ -379,12 +379,6 @@ namespace ISD {
|
|||||||
// register (or other high accuracy low latency clock source)
|
// register (or other high accuracy low latency clock source)
|
||||||
READCYCLECOUNTER,
|
READCYCLECOUNTER,
|
||||||
|
|
||||||
// READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM
|
|
||||||
// intrinsics of the same name. The first operand is a token chain, the
|
|
||||||
// other operands match the intrinsic. These produce a token chain in
|
|
||||||
// addition to a value (if any).
|
|
||||||
READPORT, WRITEPORT, READIO, WRITEIO,
|
|
||||||
|
|
||||||
// HANDLENODE node - Used as a handle for various purposes.
|
// HANDLENODE node - Used as a handle for various purposes.
|
||||||
HANDLENODE,
|
HANDLENODE,
|
||||||
|
|
||||||
|
@ -86,13 +86,6 @@ namespace Intrinsic {
|
|||||||
cttz_i16, // Count trailing zeros of short
|
cttz_i16, // Count trailing zeros of short
|
||||||
cttz_i32, // Count trailing zeros of int
|
cttz_i32, // Count trailing zeros of int
|
||||||
cttz_i64, // Count trailing zeros of long
|
cttz_i64, // Count trailing zeros of long
|
||||||
|
|
||||||
// Input/Output intrinsics.
|
|
||||||
readport,
|
|
||||||
writeport,
|
|
||||||
readio,
|
|
||||||
writeio
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End Intrinsic namespace
|
} // End Intrinsic namespace
|
||||||
|
@ -1691,68 +1691,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ISD::READPORT:
|
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1));
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
|
|
||||||
|
|
||||||
// Since these produce two values, make sure to remember that we legalized
|
|
||||||
// both of them.
|
|
||||||
AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
|
|
||||||
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
|
||||||
return Result;
|
|
||||||
case ISD::WRITEPORT:
|
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1));
|
|
||||||
Tmp3 = LegalizeOp(Node->getOperand(2));
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ISD::READIO:
|
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1));
|
|
||||||
|
|
||||||
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
|
|
||||||
case TargetLowering::Custom:
|
|
||||||
default: assert(0 && "This action not implemented for this operation!");
|
|
||||||
case TargetLowering::Legal:
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
|
|
||||||
break;
|
|
||||||
case TargetLowering::Expand:
|
|
||||||
// Replace this with a load from memory.
|
|
||||||
Result = DAG.getLoad(Node->getValueType(0), Node->getOperand(0),
|
|
||||||
Node->getOperand(1), DAG.getSrcValue(NULL));
|
|
||||||
Result = LegalizeOp(Result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since these produce two values, make sure to remember that we legalized
|
|
||||||
// both of them.
|
|
||||||
AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
|
|
||||||
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
|
||||||
return Result.getValue(Op.ResNo);
|
|
||||||
|
|
||||||
case ISD::WRITEIO:
|
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1));
|
|
||||||
Tmp3 = LegalizeOp(Node->getOperand(2));
|
|
||||||
|
|
||||||
switch (TLI.getOperationAction(Node->getOpcode(),
|
|
||||||
Node->getOperand(1).getValueType())) {
|
|
||||||
case TargetLowering::Custom:
|
|
||||||
default: assert(0 && "This action not implemented for this operation!");
|
|
||||||
case TargetLowering::Legal:
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
|
|
||||||
break;
|
|
||||||
case TargetLowering::Expand:
|
|
||||||
// Replace this with a store to memory.
|
|
||||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Node->getOperand(0),
|
|
||||||
Node->getOperand(1), Node->getOperand(2),
|
|
||||||
DAG.getSrcValue(NULL));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ISD::SHL_PARTS:
|
case ISD::SHL_PARTS:
|
||||||
case ISD::SRA_PARTS:
|
case ISD::SRA_PARTS:
|
||||||
case ISD::SRL_PARTS: {
|
case ISD::SRL_PARTS: {
|
||||||
|
@ -2691,12 +2691,6 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
|||||||
case ISD::CTTZ: return "cttz";
|
case ISD::CTTZ: return "cttz";
|
||||||
case ISD::CTLZ: return "ctlz";
|
case ISD::CTLZ: return "ctlz";
|
||||||
|
|
||||||
// IO Intrinsics
|
|
||||||
case ISD::READPORT: return "readport";
|
|
||||||
case ISD::WRITEPORT: return "writeport";
|
|
||||||
case ISD::READIO: return "readio";
|
|
||||||
case ISD::WRITEIO: return "writeio";
|
|
||||||
|
|
||||||
// Debug info
|
// Debug info
|
||||||
case ISD::LOCATION: return "location";
|
case ISD::LOCATION: return "location";
|
||||||
case ISD::DEBUG_LOC: return "debug_loc";
|
case ISD::DEBUG_LOC: return "debug_loc";
|
||||||
|
@ -968,29 +968,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||||||
visitMemIntrinsic(I, ISD::MEMMOVE);
|
visitMemIntrinsic(I, ISD::MEMMOVE);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case Intrinsic::readport:
|
|
||||||
case Intrinsic::readio: {
|
|
||||||
std::vector<MVT::ValueType> VTs;
|
|
||||||
VTs.push_back(TLI.getValueType(I.getType()));
|
|
||||||
VTs.push_back(MVT::Other);
|
|
||||||
std::vector<SDOperand> Ops;
|
|
||||||
Ops.push_back(getRoot());
|
|
||||||
Ops.push_back(getValue(I.getOperand(1)));
|
|
||||||
SDOperand Tmp = DAG.getNode(Intrinsic == Intrinsic::readport ?
|
|
||||||
ISD::READPORT : ISD::READIO, VTs, Ops);
|
|
||||||
|
|
||||||
setValue(&I, Tmp);
|
|
||||||
DAG.setRoot(Tmp.getValue(1));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case Intrinsic::writeport:
|
|
||||||
case Intrinsic::writeio:
|
|
||||||
DAG.setRoot(DAG.getNode(Intrinsic == Intrinsic::writeport ?
|
|
||||||
ISD::WRITEPORT : ISD::WRITEIO, MVT::Other,
|
|
||||||
getRoot(), getValue(I.getOperand(1)),
|
|
||||||
getValue(I.getOperand(2))));
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case Intrinsic::dbg_stoppoint: {
|
case Intrinsic::dbg_stoppoint: {
|
||||||
if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions())
|
if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions())
|
||||||
return "llvm_debugger_stop";
|
return "llvm_debugger_stop";
|
||||||
|
@ -138,14 +138,6 @@ def SDTBrcond : SDTypeProfile<0, 2, [ // brcond
|
|||||||
|
|
||||||
def SDTRet : SDTypeProfile<0, 0, []>; // ret
|
def SDTRet : SDTypeProfile<0, 0, []>; // ret
|
||||||
|
|
||||||
def SDTReadPort : SDTypeProfile<1, 1, [ // readport
|
|
||||||
SDTCisInt<0>, SDTCisInt<1>
|
|
||||||
]>;
|
|
||||||
|
|
||||||
def SDTWritePort : SDTypeProfile<0, 2, [ // writeport
|
|
||||||
SDTCisInt<0>, SDTCisInt<1>
|
|
||||||
]>;
|
|
||||||
|
|
||||||
def SDTLoad : SDTypeProfile<1, 1, [ // load
|
def SDTLoad : SDTypeProfile<1, 1, [ // load
|
||||||
SDTCisPtrTy<1>
|
SDTCisPtrTy<1>
|
||||||
]>;
|
]>;
|
||||||
@ -284,9 +276,6 @@ def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
|
|||||||
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
|
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
|
||||||
def ret : SDNode<"ISD::RET" , SDTRet, [SDNPHasChain]>;
|
def ret : SDNode<"ISD::RET" , SDTRet, [SDNPHasChain]>;
|
||||||
|
|
||||||
def readport : SDNode<"ISD::READPORT" , SDTReadPort, [SDNPHasChain]>;
|
|
||||||
def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>;
|
|
||||||
|
|
||||||
def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>;
|
def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>;
|
||||||
def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>;
|
def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>;
|
||||||
|
|
||||||
|
@ -137,15 +137,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
|||||||
setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
|
setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
|
||||||
setOperationAction(ISD::BSWAP , MVT::i16 , Expand);
|
setOperationAction(ISD::BSWAP , MVT::i16 , Expand);
|
||||||
|
|
||||||
setOperationAction(ISD::READIO , MVT::i1 , Expand);
|
|
||||||
setOperationAction(ISD::READIO , MVT::i8 , Expand);
|
|
||||||
setOperationAction(ISD::READIO , MVT::i16 , Expand);
|
|
||||||
setOperationAction(ISD::READIO , MVT::i32 , Expand);
|
|
||||||
setOperationAction(ISD::WRITEIO , MVT::i1 , Expand);
|
|
||||||
setOperationAction(ISD::WRITEIO , MVT::i8 , Expand);
|
|
||||||
setOperationAction(ISD::WRITEIO , MVT::i16 , Expand);
|
|
||||||
setOperationAction(ISD::WRITEIO , MVT::i32 , Expand);
|
|
||||||
|
|
||||||
// These should be promoted to a larger select which is supported.
|
// These should be promoted to a larger select which is supported.
|
||||||
setOperationAction(ISD::SELECT , MVT::i1 , Promote);
|
setOperationAction(ISD::SELECT , MVT::i1 , Promote);
|
||||||
setOperationAction(ISD::SELECT , MVT::i8 , Promote);
|
setOperationAction(ISD::SELECT , MVT::i8 , Promote);
|
||||||
|
@ -581,48 +581,48 @@ def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
|
|||||||
//
|
//
|
||||||
def IN8rr : I<0xEC, RawFrm, (ops),
|
def IN8rr : I<0xEC, RawFrm, (ops),
|
||||||
"in{b} {%dx, %al|%AL, %DX}",
|
"in{b} {%dx, %al|%AL, %DX}",
|
||||||
[(set AL, (readport DX))]>, Imp<[DX], [AL]>;
|
[]>, Imp<[DX], [AL]>;
|
||||||
def IN16rr : I<0xED, RawFrm, (ops),
|
def IN16rr : I<0xED, RawFrm, (ops),
|
||||||
"in{w} {%dx, %ax|%AX, %DX}",
|
"in{w} {%dx, %ax|%AX, %DX}",
|
||||||
[(set AX, (readport DX))]>, Imp<[DX], [AX]>, OpSize;
|
[]>, Imp<[DX], [AX]>, OpSize;
|
||||||
def IN32rr : I<0xED, RawFrm, (ops),
|
def IN32rr : I<0xED, RawFrm, (ops),
|
||||||
"in{l} {%dx, %eax|%EAX, %DX}",
|
"in{l} {%dx, %eax|%EAX, %DX}",
|
||||||
[(set EAX, (readport DX))]>, Imp<[DX],[EAX]>;
|
[]>, Imp<[DX],[EAX]>;
|
||||||
|
|
||||||
def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
|
def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
|
||||||
"in{b} {$port, %al|%AL, $port}",
|
"in{b} {$port, %al|%AL, $port}",
|
||||||
[(set AL, (readport i16immZExt8:$port))]>,
|
[]>,
|
||||||
Imp<[], [AL]>;
|
Imp<[], [AL]>;
|
||||||
def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
|
def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
|
||||||
"in{w} {$port, %ax|%AX, $port}",
|
"in{w} {$port, %ax|%AX, $port}",
|
||||||
[(set AX, (readport i16immZExt8:$port))]>,
|
[]>,
|
||||||
Imp<[], [AX]>, OpSize;
|
Imp<[], [AX]>, OpSize;
|
||||||
def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
|
def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
|
||||||
"in{l} {$port, %eax|%EAX, $port}",
|
"in{l} {$port, %eax|%EAX, $port}",
|
||||||
[(set EAX, (readport i16immZExt8:$port))]>,
|
[]>,
|
||||||
Imp<[],[EAX]>;
|
Imp<[],[EAX]>;
|
||||||
|
|
||||||
def OUT8rr : I<0xEE, RawFrm, (ops),
|
def OUT8rr : I<0xEE, RawFrm, (ops),
|
||||||
"out{b} {%al, %dx|%DX, %AL}",
|
"out{b} {%al, %dx|%DX, %AL}",
|
||||||
[(writeport AL, DX)]>, Imp<[DX, AL], []>;
|
[]>, Imp<[DX, AL], []>;
|
||||||
def OUT16rr : I<0xEF, RawFrm, (ops),
|
def OUT16rr : I<0xEF, RawFrm, (ops),
|
||||||
"out{w} {%ax, %dx|%DX, %AX}",
|
"out{w} {%ax, %dx|%DX, %AX}",
|
||||||
[(writeport AX, DX)]>, Imp<[DX, AX], []>, OpSize;
|
[]>, Imp<[DX, AX], []>, OpSize;
|
||||||
def OUT32rr : I<0xEF, RawFrm, (ops),
|
def OUT32rr : I<0xEF, RawFrm, (ops),
|
||||||
"out{l} {%eax, %dx|%DX, %EAX}",
|
"out{l} {%eax, %dx|%DX, %EAX}",
|
||||||
[(writeport EAX, DX)]>, Imp<[DX, EAX], []>;
|
[]>, Imp<[DX, EAX], []>;
|
||||||
|
|
||||||
def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
|
def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
|
||||||
"out{b} {%al, $port|$port, %AL}",
|
"out{b} {%al, $port|$port, %AL}",
|
||||||
[(writeport AL, i16immZExt8:$port)]>,
|
[]>,
|
||||||
Imp<[AL], []>;
|
Imp<[AL], []>;
|
||||||
def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
|
def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
|
||||||
"out{w} {%ax, $port|$port, %AX}",
|
"out{w} {%ax, $port|$port, %AX}",
|
||||||
[(writeport AX, i16immZExt8:$port)]>,
|
[]>,
|
||||||
Imp<[AX], []>, OpSize;
|
Imp<[AX], []>, OpSize;
|
||||||
def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
|
def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
|
||||||
"out{l} {%eax, $port|$port, %EAX}",
|
"out{l} {%eax, $port|$port, %EAX}",
|
||||||
[(writeport EAX, i16immZExt8:$port)]>,
|
[]>,
|
||||||
Imp<[EAX], []>;
|
Imp<[EAX], []>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -265,8 +265,6 @@ unsigned Function::getIntrinsicID() const {
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (Name == "llvm.returnaddress") return Intrinsic::returnaddress;
|
if (Name == "llvm.returnaddress") return Intrinsic::returnaddress;
|
||||||
if (Name == "llvm.readport") return Intrinsic::readport;
|
|
||||||
if (Name == "llvm.readio") return Intrinsic::readio;
|
|
||||||
if (Name == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
|
if (Name == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
@ -283,10 +281,6 @@ unsigned Function::getIntrinsicID() const {
|
|||||||
if (Name == "llvm.va_end") return Intrinsic::vaend;
|
if (Name == "llvm.va_end") return Intrinsic::vaend;
|
||||||
if (Name == "llvm.va_start") return Intrinsic::vastart;
|
if (Name == "llvm.va_start") return Intrinsic::vastart;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
|
||||||
if (Name == "llvm.writeport") return Intrinsic::writeport;
|
|
||||||
if (Name == "llvm.writeio") return Intrinsic::writeio;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// The "llvm." namespace is reserved!
|
// The "llvm." namespace is reserved!
|
||||||
assert(!"Unknown LLVM intrinsic function!");
|
assert(!"Unknown LLVM intrinsic function!");
|
||||||
|
@ -702,51 +702,6 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
|||||||
NumArgs = 1;
|
NumArgs = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Verify that read and write port have integral parameters of the correct
|
|
||||||
// signed-ness.
|
|
||||||
case Intrinsic::writeport:
|
|
||||||
Assert1(FT->getNumParams() == 2,
|
|
||||||
"Illegal # arguments for intrinsic function!", IF);
|
|
||||||
Assert1(FT->getParamType(0)->isIntegral(),
|
|
||||||
"First argument not unsigned int!", IF);
|
|
||||||
Assert1(FT->getParamType(1)->isUnsigned(),
|
|
||||||
"First argument not unsigned int!", IF);
|
|
||||||
NumArgs = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Intrinsic::writeio:
|
|
||||||
Assert1(FT->getNumParams() == 2,
|
|
||||||
"Illegal # arguments for intrinsic function!", IF);
|
|
||||||
Assert1(FT->getParamType(0)->isFirstClassType(),
|
|
||||||
"First argument not a first class type!", IF);
|
|
||||||
Assert1(isa<PointerType>(FT->getParamType(1)),
|
|
||||||
"Second argument not a pointer!", IF);
|
|
||||||
NumArgs = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Intrinsic::readport:
|
|
||||||
Assert1(FT->getNumParams() == 1,
|
|
||||||
"Illegal # arguments for intrinsic function!", IF);
|
|
||||||
Assert1(FT->getReturnType()->isFirstClassType(),
|
|
||||||
"Return type is not a first class type!", IF);
|
|
||||||
Assert1(FT->getParamType(0)->isUnsigned(),
|
|
||||||
"First argument not unsigned int!", IF);
|
|
||||||
NumArgs = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Intrinsic::readio: {
|
|
||||||
const PointerType *ParamType = dyn_cast<PointerType>(FT->getParamType(0));
|
|
||||||
const Type *ReturnType = FT->getReturnType();
|
|
||||||
|
|
||||||
Assert1(FT->getNumParams() == 1,
|
|
||||||
"Illegal # arguments for intrinsic function!", IF);
|
|
||||||
Assert1(ParamType, "First argument not a pointer!", IF);
|
|
||||||
Assert1(ParamType->getElementType() == ReturnType,
|
|
||||||
"Pointer type doesn't match return type!", IF);
|
|
||||||
NumArgs = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Intrinsic::isunordered_f32:
|
case Intrinsic::isunordered_f32:
|
||||||
Assert1(FT->getNumParams() == 2,
|
Assert1(FT->getNumParams() == 2,
|
||||||
"Illegal # arguments for intrinsic function!", IF);
|
"Illegal # arguments for intrinsic function!", IF);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user