Rename intel to x86.
x86 is the more accurate name, as there are non-Intel x86 implementations. Fixes #263.
This commit is contained in:
@@ -174,7 +174,7 @@ is emitted, there are opcodes for every native instruction that can be
|
|||||||
generated. There is a lot of overlap between different ISAs, so for example the
|
generated. There is a lot of overlap between different ISAs, so for example the
|
||||||
:cton:inst:`iadd_imm` instruction is used by every ISA that can add an
|
:cton:inst:`iadd_imm` instruction is used by every ISA that can add an
|
||||||
immediate integer to a register. A simple RISC ISA like RISC-V can be defined
|
immediate integer to a register. A simple RISC ISA like RISC-V can be defined
|
||||||
with only shared instructions, while an Intel ISA needs a number of specific
|
with only shared instructions, while x86 needs a number of specific
|
||||||
instructions to model addressing modes.
|
instructions to model addressing modes.
|
||||||
|
|
||||||
Undefined behavior
|
Undefined behavior
|
||||||
|
|||||||
@@ -998,20 +998,20 @@ ISA-specific instructions
|
|||||||
Target ISAs can define supplemental instructions that do not make sense to
|
Target ISAs can define supplemental instructions that do not make sense to
|
||||||
support generally.
|
support generally.
|
||||||
|
|
||||||
Intel
|
x86
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Instructions that can only be used by the Intel target ISA.
|
Instructions that can only be used by the x86 target ISA.
|
||||||
|
|
||||||
.. autoinst:: isa.intel.instructions.sdivmodx
|
.. autoinst:: isa.x86.instructions.sdivmodx
|
||||||
.. autoinst:: isa.intel.instructions.udivmodx
|
.. autoinst:: isa.x86.instructions.udivmodx
|
||||||
.. autoinst:: isa.intel.instructions.cvtt2si
|
.. autoinst:: isa.x86.instructions.cvtt2si
|
||||||
.. autoinst:: isa.intel.instructions.fmin
|
.. autoinst:: isa.x86.instructions.fmin
|
||||||
.. autoinst:: isa.intel.instructions.fmax
|
.. autoinst:: isa.x86.instructions.fmax
|
||||||
.. autoinst:: isa.intel.instructions.bsf
|
.. autoinst:: isa.x86.instructions.bsf
|
||||||
.. autoinst:: isa.intel.instructions.bsr
|
.. autoinst:: isa.x86.instructions.bsr
|
||||||
.. autoinst:: isa.intel.instructions.push
|
.. autoinst:: isa.x86.instructions.push
|
||||||
.. autoinst:: isa.intel.instructions.pop
|
.. autoinst:: isa.x86.instructions.pop
|
||||||
|
|
||||||
Instruction groups
|
Instruction groups
|
||||||
==================
|
==================
|
||||||
@@ -1023,7 +1023,7 @@ group.
|
|||||||
|
|
||||||
Target ISAs may define further instructions in their own instruction groups:
|
Target ISAs may define further instructions in their own instruction groups:
|
||||||
|
|
||||||
.. autoinstgroup:: isa.intel.instructions.GROUP
|
.. autoinstgroup:: isa.x86.instructions.GROUP
|
||||||
|
|
||||||
Implementation limits
|
Implementation limits
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ Fixed register operands
|
|||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Some instructions use hard-coded input and output registers for some value
|
Some instructions use hard-coded input and output registers for some value
|
||||||
operands. An example is the ``pblendvb`` Intel SSE instruction which takes one
|
operands. An example is the ``pblendvb`` x86 SSE instruction which takes one
|
||||||
of its three value operands in the hard-coded ``%xmm0`` register::
|
of its three value operands in the hard-coded ``%xmm0`` register::
|
||||||
|
|
||||||
XMM0 = FPR[0]
|
XMM0 = FPR[0]
|
||||||
@@ -439,7 +439,7 @@ The definitions for each supported target live in a package under
|
|||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. automodule:: isa.riscv
|
.. automodule:: isa.riscv
|
||||||
.. automodule:: isa.intel
|
.. automodule:: isa.x86
|
||||||
.. automodule:: isa.arm32
|
.. automodule:: isa.arm32
|
||||||
.. automodule:: isa.arm64
|
.. automodule:: isa.arm64
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ Different register banks
|
|||||||
|
|
||||||
Instructions with fixed operands
|
Instructions with fixed operands
|
||||||
Some instructions use a fixed register for an operand. This happens on the
|
Some instructions use a fixed register for an operand. This happens on the
|
||||||
Intel ISAs:
|
x86 ISAs:
|
||||||
|
|
||||||
- Dynamic shift and rotate instructions take the shift amount in CL.
|
- Dynamic shift and rotate instructions take the shift amount in CL.
|
||||||
- Division instructions use RAX and RDX for both input and output operands.
|
- Division instructions use RAX and RDX for both input and output operands.
|
||||||
@@ -109,7 +109,7 @@ ABI boundaries
|
|||||||
Aliasing registers
|
Aliasing registers
|
||||||
Different registers sometimes share the same bits in the register bank.
|
Different registers sometimes share the same bits in the register bank.
|
||||||
This can make it difficult to measure register pressure. For example, the
|
This can make it difficult to measure register pressure. For example, the
|
||||||
Intel registers RAX, EAX, AX, AL, and AH overlap.
|
x86 registers RAX, EAX, AX, AL, and AH overlap.
|
||||||
|
|
||||||
If only one of the aliasing registers can be used at a time, the aliasing
|
If only one of the aliasing registers can be used at a time, the aliasing
|
||||||
doesn't cause problems since the registers can simply be counted as one
|
doesn't cause problems since the registers can simply be counted as one
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test compile
|
test compile
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %foo(i64, i64, i64, i32) -> b1 system_v {
|
function %foo(i64, i64, i64, i32) -> b1 system_v {
|
||||||
ebb3(v0: i64, v1: i64, v2: i64, v3: i32):
|
ebb3(v0: i64, v1: i64, v2: i64, v3: i32):
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
; Test the legalization of function signatures.
|
; Test the legalization of function signatures.
|
||||||
test legalizer
|
test legalizer
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
; Test the legalization of function signatures.
|
; Test the legalization of function signatures.
|
||||||
test legalizer
|
test legalizer
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
|
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
set allones_funcaddrs
|
set allones_funcaddrs
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/allones_funcaddrs32.cton | llvm-mc -show-encoding -triple=i386
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/allones_funcaddrs32.cton | llvm-mc -show-encoding -triple=i386
|
||||||
;
|
;
|
||||||
|
|
||||||
; Tests from binary32.cton affected by allones_funcaddrs.
|
; Tests from binary32.cton affected by allones_funcaddrs.
|
||||||
@@ -3,11 +3,11 @@ test binemit
|
|||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
set allones_funcaddrs
|
set allones_funcaddrs
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/allones_funcaddrs64.cton | llvm-mc -show-encoding -triple=x86_64
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/allones_funcaddrs64.cton | llvm-mc -show-encoding -triple=x86_64
|
||||||
;
|
;
|
||||||
|
|
||||||
; Tests from binary64.cton affected by allones_funcaddrs.
|
; Tests from binary64.cton affected by allones_funcaddrs.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
test compile
|
test compile
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
|
|
||||||
; clz/ctz on 64 bit operands
|
; clz/ctz on 64 bit operands
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/baseline_clz_ctz_popcount_encoding.cton | llvm-mc -show-encoding -triple=x86_64
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/baseline_clz_ctz_popcount_encoding.cton | llvm-mc -show-encoding -triple=x86_64
|
||||||
;
|
;
|
||||||
|
|
||||||
function %Foo() {
|
function %Foo() {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
; Binary emission of 32-bit floating point code.
|
; Binary emission of 32-bit floating point code.
|
||||||
test binemit
|
test binemit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary32-float.cton | llvm-mc -show-encoding -triple=i386
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/binary32-float.cton | llvm-mc -show-encoding -triple=i386
|
||||||
;
|
;
|
||||||
|
|
||||||
function %F32() {
|
function %F32() {
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
; binary emission of x86-32 code.
|
; binary emission of x86-32 code.
|
||||||
test binemit
|
test binemit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary32.cton | llvm-mc -show-encoding -triple=i386
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/binary32.cton | llvm-mc -show-encoding -triple=i386
|
||||||
;
|
;
|
||||||
|
|
||||||
function %I32() {
|
function %I32() {
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary64-float.cton | llvm-mc -show-encoding -triple=x86_64
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/binary64-float.cton | llvm-mc -show-encoding -triple=x86_64
|
||||||
;
|
;
|
||||||
|
|
||||||
function %F32() {
|
function %F32() {
|
||||||
@@ -3,11 +3,11 @@ test binemit
|
|||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
set is_pic
|
set is_pic
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary64-pic.cton | llvm-mc -show-encoding -triple=x86_64
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/binary64-pic.cton | llvm-mc -show-encoding -triple=x86_64
|
||||||
;
|
;
|
||||||
|
|
||||||
; Tests for i64 instructions.
|
; Tests for i64 instructions.
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
;
|
;
|
||||||
; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary64.cton | llvm-mc -show-encoding -triple=x86_64
|
; sed -ne 's/^ *; asm: *//p' filetests/isa/x86/binary64.cton | llvm-mc -show-encoding -triple=x86_64
|
||||||
;
|
;
|
||||||
|
|
||||||
; Tests for i64 instructions.
|
; Tests for i64 instructions.
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
; Test the custom legalizations.
|
; Test the custom legalizations.
|
||||||
test legalizer
|
test legalizer
|
||||||
isa intel
|
isa x86
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
; regex: EBB=ebb\d+
|
; regex: EBB=ebb\d+
|
||||||
@@ -3,7 +3,7 @@ test legalizer
|
|||||||
set is_64bit
|
set is_64bit
|
||||||
; See also legalize-div.cton.
|
; See also legalize-div.cton.
|
||||||
set avoid_div_traps=1
|
set avoid_div_traps=1
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
; regex: EBB=ebb\d+
|
; regex: EBB=ebb\d+
|
||||||
@@ -3,7 +3,7 @@ test legalizer
|
|||||||
set is_64bit
|
set is_64bit
|
||||||
; See also legalize-div-traps.cton.
|
; See also legalize-div-traps.cton.
|
||||||
set avoid_div_traps=0
|
set avoid_div_traps=0
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
; regex: EBB=ebb\d+
|
; regex: EBB=ebb\d+
|
||||||
@@ -3,7 +3,7 @@ test legalizer
|
|||||||
; Pre-SSE 4.1, we need to use runtime library calls for floating point rounding operations.
|
; Pre-SSE 4.1, we need to use runtime library calls for floating point rounding operations.
|
||||||
set is_64bit
|
set is_64bit
|
||||||
set is_pic
|
set is_pic
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
function %floor(f32) -> f32 {
|
function %floor(f32) -> f32 {
|
||||||
ebb0(v0: f32):
|
ebb0(v0: f32):
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
; Test the legalization of memory objects.
|
; Test the legalization of memory objects.
|
||||||
test legalizer
|
test legalizer
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
; regex: EBB=ebb\d+
|
; regex: EBB=ebb\d+
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
test compile
|
test compile
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; umulhi/smulhi on 64 bit operands
|
; umulhi/smulhi on 64 bit operands
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ test compile
|
|||||||
set is_64bit
|
set is_64bit
|
||||||
set is_compressed
|
set is_compressed
|
||||||
set is_pic
|
set is_pic
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; An empty function.
|
; An empty function.
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
test postopt
|
test postopt
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; Test that compare+branch sequences are folded effectively on x86.
|
; Test that compare+branch sequences are folded effectively on x86.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
test preopt
|
test preopt
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; Cases where the denominator is created by an iconst
|
; Cases where the denominator is created by an iconst
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
test preopt
|
test preopt
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; -------- U32 --------
|
; -------- U32 --------
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
test preopt
|
test preopt
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; -------- U32 --------
|
; -------- U32 --------
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
test preopt
|
test preopt
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; -------- U32 --------
|
; -------- U32 --------
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
test preopt
|
test preopt
|
||||||
isa intel baseline
|
isa x86 baseline
|
||||||
|
|
||||||
; -------- U32 --------
|
; -------- U32 --------
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test preopt
|
test preopt
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
function %iadd_imm(i32) -> i32 {
|
function %iadd_imm(i32) -> i32 {
|
||||||
ebb0(v0: i32):
|
ebb0(v0: i32):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %value_aliases(i32, f32, i64 vmctx) spiderwasm {
|
function %value_aliases(i32, f32, i64 vmctx) spiderwasm {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Reported as https://github.com/Cretonne/cretonne/issues/207
|
; Reported as https://github.com/Cretonne/cretonne/issues/207
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Reported as https://github.com/Cretonne/cretonne/issues/216 from the Binaryen fuzzer.
|
; Reported as https://github.com/Cretonne/cretonne/issues/216 from the Binaryen fuzzer.
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8]) system_v {
|
function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8]) system_v {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
; regex: REG=%r([abcd]x|[sd]i)
|
; regex: REG=%r([abcd]x|[sd]i)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; This test case would create an EBB parameter that was a ghost value.
|
; This test case would create an EBB parameter that was a ghost value.
|
||||||
; The coalescer would insert a copy of the ghost value, leading to verifier errors.
|
; The coalescer would insert a copy of the ghost value, leading to verifier errors.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; This test covers the troubles when values with global live ranges are defined
|
; This test covers the troubles when values with global live ranges are defined
|
||||||
; by instructions with constrained register classes.
|
; by instructions with constrained register classes.
|
||||||
;
|
;
|
||||||
; The icmp_imm instrutions write their b1 result to the ABCD register class on
|
; The icmp_imm instrutions write their b1 result to the ABCD register class on
|
||||||
; 32-bit Intel. So if we define 5 live values, they can't all fit.
|
; 32-bit x86. So if we define 5 live values, they can't all fit.
|
||||||
function %global_constraints(i32) {
|
function %global_constraints(i32) {
|
||||||
ebb0(v0: i32):
|
ebb0(v0: i32):
|
||||||
v1 = icmp_imm eq v0, 1
|
v1 = icmp_imm eq v0, 1
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %foo() system_v {
|
function %foo() system_v {
|
||||||
ebb4:
|
ebb4:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] spiderwasm {
|
function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] spiderwasm {
|
||||||
ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64):
|
ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64):
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Test combinations of constraints.
|
; Test combinations of constraints.
|
||||||
;
|
;
|
||||||
; The Intel ushr instruction requires its second operand to be passed in %rcx and its output is
|
; The x86 ushr instruction requires its second operand to be passed in %rcx and its output is
|
||||||
; tied to the first input operand.
|
; tied to the first input operand.
|
||||||
;
|
;
|
||||||
; If we pass the same value to both operands, both constraints must be satisfied.
|
; If we pass the same value to both operands, both constraints must be satisfied.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %test(i64) -> i64 system_v {
|
function %test(i64) -> i64 system_v {
|
||||||
ebb0(v0: i64):
|
ebb0(v0: i64):
|
||||||
v2 = iconst.i64 12
|
v2 = iconst.i64 12
|
||||||
; This division clobbers two of its fixed input registers on Intel.
|
; This division clobbers two of its fixed input registers on x86.
|
||||||
; These are FixedTied constraints that the spiller needs to resolve.
|
; These are FixedTied constraints that the spiller needs to resolve.
|
||||||
v5 = udiv v0, v2
|
v5 = udiv v0, v2
|
||||||
v6 = iconst.i64 13
|
v6 = iconst.i64 13
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %pr165() system_v {
|
function %pr165() system_v {
|
||||||
ebb0:
|
ebb0:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; Test case found by the Binaryen fuzzer.
|
; Test case found by the Binaryen fuzzer.
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit
|
set is_64bit
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; This function contains unreachable blocks which trip up the register
|
; This function contains unreachable blocks which trip up the register
|
||||||
; allocator if they don't get cleared out.
|
; allocator if they don't get cleared out.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
test regalloc
|
test regalloc
|
||||||
|
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
test verifier
|
test verifier
|
||||||
isa intel
|
isa x86
|
||||||
|
|
||||||
; Simple, correct use of CPU flags.
|
; Simple, correct use of CPU flags.
|
||||||
function %simple(i32) -> i32 {
|
function %simple(i32) -> i32 {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %br_if(i32) -> i32 {
|
function %br_if(i32) -> i32 {
|
||||||
ebb0(v0: i32):
|
ebb0(v0: i32):
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %i32_wrap_i64(i64) -> i32 {
|
function %i32_wrap_i64(i64) -> i32 {
|
||||||
ebb0(v0: i64):
|
ebb0(v0: i64):
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Constants.
|
; Constants.
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %f32_eq(f32, f32) -> i32 {
|
function %f32_eq(f32, f32) -> i32 {
|
||||||
ebb0(v0: f32, v1: f32):
|
ebb0(v0: f32, v1: f32):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test compile
|
|||||||
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
||||||
; explicitly mention the pointer width.
|
; explicitly mention the pointer width.
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %f32_load(i32, i64 vmctx) -> f32 {
|
function %f32_load(i32, i64 vmctx) -> f32 {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Constants.
|
; Constants.
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %f64_eq(f64, f64) -> i32 {
|
function %f64_eq(f64, f64) -> i32 {
|
||||||
ebb0(v0: f64, v1: f64):
|
ebb0(v0: f64, v1: f64):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test compile
|
|||||||
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
||||||
; explicitly mention the pointer width.
|
; explicitly mention the pointer width.
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %f64_load(i32, i64 vmctx) -> f64 {
|
function %f64_load(i32, i64 vmctx) -> f64 {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Constants.
|
; Constants.
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %i32_eqz(i32) -> i32 {
|
function %i32_eqz(i32) -> i32 {
|
||||||
ebb0(v0: i32):
|
ebb0(v0: i32):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test compile
|
|||||||
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
||||||
; explicitly mention the pointer width.
|
; explicitly mention the pointer width.
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %i32_load(i32, i64 vmctx) -> i32 {
|
function %i32_load(i32, i64 vmctx) -> i32 {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
; Constants.
|
; Constants.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %i64_eqz(i64) -> i32 {
|
function %i64_eqz(i64) -> i32 {
|
||||||
ebb0(v0: i64):
|
ebb0(v0: i64):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test compile
|
|||||||
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
; We only test on 64-bit since the heap_addr instructions and vmctx parameters
|
||||||
; explicitly mention the pointer width.
|
; explicitly mention the pointer width.
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %i64_load(i32, i64 vmctx) -> i64 {
|
function %i64_load(i32, i64 vmctx) -> i64 {
|
||||||
gv0 = vmctx
|
gv0 = vmctx
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
test compile
|
test compile
|
||||||
|
|
||||||
set is_64bit=0
|
set is_64bit=0
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
set is_64bit=1
|
set is_64bit=1
|
||||||
isa intel haswell
|
isa x86 haswell
|
||||||
|
|
||||||
function %select_i32(i32, i32, i32) -> i32 {
|
function %select_i32(i32, i32, i32) -> i32 {
|
||||||
ebb0(v0: i32, v1: i32, v2: i32):
|
ebb0(v0: i32, v1: i32, v2: i32):
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ fn main() {
|
|||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum Isa {
|
enum Isa {
|
||||||
Riscv,
|
Riscv,
|
||||||
Intel,
|
X86,
|
||||||
Arm32,
|
Arm32,
|
||||||
Arm64,
|
Arm64,
|
||||||
}
|
}
|
||||||
@@ -103,14 +103,14 @@ impl Isa {
|
|||||||
|
|
||||||
/// Returns all supported isa targets.
|
/// Returns all supported isa targets.
|
||||||
fn all() -> [Isa; 4] {
|
fn all() -> [Isa; 4] {
|
||||||
[Isa::Riscv, Isa::Intel, Isa::Arm32, Isa::Arm64]
|
[Isa::Riscv, Isa::X86, Isa::Arm32, Isa::Arm64]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns name of the isa target.
|
/// Returns name of the isa target.
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
match *self {
|
match *self {
|
||||||
Isa::Riscv => "riscv",
|
Isa::Riscv => "riscv",
|
||||||
Isa::Intel => "intel",
|
Isa::X86 => "x86",
|
||||||
Isa::Arm32 => "arm32",
|
Isa::Arm32 => "arm32",
|
||||||
Isa::Arm64 => "arm64",
|
Isa::Arm64 => "arm64",
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ impl Isa {
|
|||||||
fn is_arch_applicable(&self, arch: &str) -> bool {
|
fn is_arch_applicable(&self, arch: &str) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Isa::Riscv => arch == "riscv",
|
Isa::Riscv => arch == "riscv",
|
||||||
Isa::Intel => ["x86_64", "i386", "i586", "i686"].contains(&arch),
|
Isa::X86 => ["x86_64", "i386", "i586", "i686"].contains(&arch),
|
||||||
Isa::Arm32 => arch.starts_with("arm") || arch.starts_with("thumb"),
|
Isa::Arm32 => arch.starts_with("arm") || arch.starts_with("thumb"),
|
||||||
Isa::Arm64 => arch == "aarch64",
|
Isa::Arm64 => arch == "aarch64",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ spiderwasm_prologue_words = NumSetting(
|
|||||||
|
|
||||||
This setting configures the number of pointer-sized words pushed on the
|
This setting configures the number of pointer-sized words pushed on the
|
||||||
stack when the Cretonne-generated code is entered. This includes the
|
stack when the Cretonne-generated code is entered. This includes the
|
||||||
pushed return address on Intel ISAs.
|
pushed return address on x86.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ architecture supported by Cretonne.
|
|||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.isa import TargetISA # noqa
|
from cdsl.isa import TargetISA # noqa
|
||||||
from . import riscv, intel, arm32, arm64
|
from . import riscv, x86, arm32, arm64
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from typing import List # noqa
|
from typing import List # noqa
|
||||||
@@ -21,4 +21,4 @@ def all_isas():
|
|||||||
Get a list of all the supported target ISAs. Each target ISA is represented
|
Get a list of all the supported target ISAs. Each target ISA is represented
|
||||||
as a :py:class:`cretonne.TargetISA` instance.
|
as a :py:class:`cretonne.TargetISA` instance.
|
||||||
"""
|
"""
|
||||||
return [riscv.ISA, intel.ISA, arm32.ISA, arm64.ISA]
|
return [riscv.ISA, x86.ISA, arm32.ISA, arm64.ISA]
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
"""
|
|
||||||
Intel Target Architecture
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
This target ISA generates code for Intel CPUs with two separate CPU modes:
|
|
||||||
|
|
||||||
`I32`
|
|
||||||
IA-32 architecture, also known as 'x86'. Generates code for the Intel 386
|
|
||||||
and later processors in 32-bit mode.
|
|
||||||
`I64`
|
|
||||||
Intel 64 architecture, also known as 'x86-64, 'x64', and 'amd64'. Intel and
|
|
||||||
AMD CPUs running in 64-bit mode.
|
|
||||||
|
|
||||||
Floating point is supported only on CPUs with support for SSE2 or later. There
|
|
||||||
is no x87 floating point support.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
from . import defs
|
|
||||||
from . import encodings, settings, registers # noqa
|
|
||||||
|
|
||||||
# Re-export the primary target ISA definition.
|
|
||||||
ISA = defs.ISA.finish()
|
|
||||||
21
lib/cretonne/meta/isa/x86/__init__.py
Normal file
21
lib/cretonne/meta/isa/x86/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
"""
|
||||||
|
x86 Target Architecture
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
This target ISA generates code for x86 CPUs with two separate CPU modes:
|
||||||
|
|
||||||
|
`I32`
|
||||||
|
32-bit x86 architecture, also known as 'IA-32', also sometimes referred
|
||||||
|
to as 'i386', however note that Cretonne depends on instructions not
|
||||||
|
in the original `i386`, such as SSE2, CMOVcc, and UD2.
|
||||||
|
|
||||||
|
`I64`
|
||||||
|
x86-64 architecture, also known as 'AMD64`, `Intel 64`, and 'x64'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from . import defs
|
||||||
|
from . import encodings, settings, registers # noqa
|
||||||
|
|
||||||
|
# Re-export the primary target ISA definition.
|
||||||
|
ISA = defs.ISA.finish()
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Intel definitions.
|
x86 definitions.
|
||||||
|
|
||||||
Commonly used definitions.
|
Commonly used definitions.
|
||||||
"""
|
"""
|
||||||
@@ -9,7 +9,7 @@ import base.instructions
|
|||||||
from . import instructions as x86
|
from . import instructions as x86
|
||||||
from base.immediates import floatcc
|
from base.immediates import floatcc
|
||||||
|
|
||||||
ISA = TargetISA('intel', [base.instructions.GROUP, x86.GROUP])
|
ISA = TargetISA('x86', [base.instructions.GROUP, x86.GROUP])
|
||||||
|
|
||||||
# CPU modes for 32-bit and 64-bit operation.
|
# CPU modes for 32-bit and 64-bit operation.
|
||||||
X86_64 = CPUMode('I64', ISA)
|
X86_64 = CPUMode('I64', ISA)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Intel Encodings.
|
x86 Encodings.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.predicates import IsUnsignedInt, Not, And
|
from cdsl.predicates import IsUnsignedInt, Not, And
|
||||||
@@ -9,7 +9,7 @@ from .defs import X86_64, X86_32
|
|||||||
from . import recipes as r
|
from . import recipes as r
|
||||||
from . import settings as cfg
|
from . import settings as cfg
|
||||||
from . import instructions as x86
|
from . import instructions as x86
|
||||||
from .legalize import intel_expand
|
from .legalize import x86_expand
|
||||||
from base.legalize import narrow, expand_flags
|
from base.legalize import narrow, expand_flags
|
||||||
from base.settings import allones_funcaddrs, is_pic
|
from base.settings import allones_funcaddrs, is_pic
|
||||||
from .settings import use_sse41
|
from .settings import use_sse41
|
||||||
@@ -26,18 +26,18 @@ X86_32.legalize_monomorphic(expand_flags)
|
|||||||
X86_32.legalize_type(
|
X86_32.legalize_type(
|
||||||
default=narrow,
|
default=narrow,
|
||||||
b1=expand_flags,
|
b1=expand_flags,
|
||||||
i32=intel_expand,
|
i32=x86_expand,
|
||||||
f32=intel_expand,
|
f32=x86_expand,
|
||||||
f64=intel_expand)
|
f64=x86_expand)
|
||||||
|
|
||||||
X86_64.legalize_monomorphic(expand_flags)
|
X86_64.legalize_monomorphic(expand_flags)
|
||||||
X86_64.legalize_type(
|
X86_64.legalize_type(
|
||||||
default=narrow,
|
default=narrow,
|
||||||
b1=expand_flags,
|
b1=expand_flags,
|
||||||
i32=intel_expand,
|
i32=x86_expand,
|
||||||
i64=intel_expand,
|
i64=x86_expand,
|
||||||
f32=intel_expand,
|
f32=x86_expand,
|
||||||
f64=intel_expand)
|
f64=x86_expand)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Supplementary instruction definitions for Intel.
|
Supplementary instruction definitions for x86.
|
||||||
|
|
||||||
This module defines additional instructions that are useful only to the Intel
|
This module defines additional instructions that are useful only to the x86
|
||||||
target ISA.
|
target ISA.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ from cdsl.typevar import TypeVar
|
|||||||
from cdsl.instructions import Instruction, InstructionGroup
|
from cdsl.instructions import Instruction, InstructionGroup
|
||||||
|
|
||||||
|
|
||||||
GROUP = InstructionGroup("x86", "Intel-specific instruction set")
|
GROUP = InstructionGroup("x86", "x86-specific instruction set")
|
||||||
|
|
||||||
iWord = TypeVar('iWord', 'A scalar integer machine word', ints=(32, 64))
|
iWord = TypeVar('iWord', 'A scalar integer machine word', ints=(32, 64))
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ y = Operand('y', Float)
|
|||||||
|
|
||||||
fmin = Instruction(
|
fmin = Instruction(
|
||||||
'x86_fmin', r"""
|
'x86_fmin', r"""
|
||||||
Floating point minimum with Intel semantics.
|
Floating point minimum with x86 semantics.
|
||||||
|
|
||||||
This is equivalent to the C ternary operator `x < y ? x : y` which
|
This is equivalent to the C ternary operator `x < y ? x : y` which
|
||||||
differs from :inst:`fmin` when either operand is NaN or when comparing
|
differs from :inst:`fmin` when either operand is NaN or when comparing
|
||||||
@@ -111,7 +111,7 @@ fmin = Instruction(
|
|||||||
|
|
||||||
fmax = Instruction(
|
fmax = Instruction(
|
||||||
'x86_fmax', r"""
|
'x86_fmax', r"""
|
||||||
Floating point maximum with Intel semantics.
|
Floating point maximum with x86 semantics.
|
||||||
|
|
||||||
This is equivalent to the C ternary operator `x > y ? x : y` which
|
This is equivalent to the C ternary operator `x > y ? x : y` which
|
||||||
differs from :inst:`fmax` when either operand is NaN or when comparing
|
differs from :inst:`fmax` when either operand is NaN or when comparing
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Custom legalization patterns for Intel.
|
Custom legalization patterns for x86.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.ast import Var
|
from cdsl.ast import Var
|
||||||
@@ -10,12 +10,12 @@ from base import instructions as insts
|
|||||||
from . import instructions as x86
|
from . import instructions as x86
|
||||||
from .defs import ISA
|
from .defs import ISA
|
||||||
|
|
||||||
intel_expand = XFormGroup(
|
x86_expand = XFormGroup(
|
||||||
'intel_expand',
|
'x86_expand',
|
||||||
"""
|
"""
|
||||||
Legalize instructions by expansion.
|
Legalize instructions by expansion.
|
||||||
|
|
||||||
Use Intel-specific instructions if needed.
|
Use x86-specific instructions if needed.
|
||||||
""",
|
""",
|
||||||
isa=ISA, chain=shared.expand_flags)
|
isa=ISA, chain=shared.expand_flags)
|
||||||
|
|
||||||
@@ -32,23 +32,23 @@ a2 = Var('a2')
|
|||||||
#
|
#
|
||||||
# The srem expansion requires custom code because srem INT_MIN, -1 is not
|
# The srem expansion requires custom code because srem INT_MIN, -1 is not
|
||||||
# allowed to trap. The other ops need to check avoid_div_traps.
|
# allowed to trap. The other ops need to check avoid_div_traps.
|
||||||
intel_expand.custom_legalize(insts.sdiv, 'expand_sdivrem')
|
x86_expand.custom_legalize(insts.sdiv, 'expand_sdivrem')
|
||||||
intel_expand.custom_legalize(insts.srem, 'expand_sdivrem')
|
x86_expand.custom_legalize(insts.srem, 'expand_sdivrem')
|
||||||
intel_expand.custom_legalize(insts.udiv, 'expand_udivrem')
|
x86_expand.custom_legalize(insts.udiv, 'expand_udivrem')
|
||||||
intel_expand.custom_legalize(insts.urem, 'expand_udivrem')
|
x86_expand.custom_legalize(insts.urem, 'expand_udivrem')
|
||||||
|
|
||||||
#
|
#
|
||||||
# Double length (widening) multiplication
|
# Double length (widening) multiplication
|
||||||
#
|
#
|
||||||
resLo = Var('resLo')
|
resLo = Var('resLo')
|
||||||
resHi = Var('resHi')
|
resHi = Var('resHi')
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
resHi << insts.umulhi(x, y),
|
resHi << insts.umulhi(x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
(resLo, resHi) << x86.umulx(x, y)
|
(resLo, resHi) << x86.umulx(x, y)
|
||||||
))
|
))
|
||||||
|
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
resHi << insts.smulhi(x, y),
|
resHi << insts.smulhi(x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
(resLo, resHi) << x86.smulx(x, y)
|
(resLo, resHi) << x86.smulx(x, y)
|
||||||
@@ -61,14 +61,14 @@ intel_expand.legalize(
|
|||||||
# patterns.
|
# patterns.
|
||||||
|
|
||||||
# Equality needs an explicit `ord` test which checks the parity bit.
|
# Equality needs an explicit `ord` test which checks the parity bit.
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.fcmp(floatcc.eq, x, y),
|
a << insts.fcmp(floatcc.eq, x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
a1 << insts.fcmp(floatcc.ord, x, y),
|
a1 << insts.fcmp(floatcc.ord, x, y),
|
||||||
a2 << insts.fcmp(floatcc.ueq, x, y),
|
a2 << insts.fcmp(floatcc.ueq, x, y),
|
||||||
a << insts.band(a1, a2)
|
a << insts.band(a1, a2)
|
||||||
))
|
))
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.fcmp(floatcc.ne, x, y),
|
a << insts.fcmp(floatcc.ne, x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
a1 << insts.fcmp(floatcc.uno, x, y),
|
a1 << insts.fcmp(floatcc.uno, x, y),
|
||||||
@@ -82,21 +82,21 @@ for cc, rev_cc in [
|
|||||||
(floatcc.le, floatcc.ge),
|
(floatcc.le, floatcc.ge),
|
||||||
(floatcc.ugt, floatcc.ult),
|
(floatcc.ugt, floatcc.ult),
|
||||||
(floatcc.uge, floatcc.ule)]:
|
(floatcc.uge, floatcc.ule)]:
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.fcmp(cc, x, y),
|
a << insts.fcmp(cc, x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
a << insts.fcmp(rev_cc, y, x)
|
a << insts.fcmp(rev_cc, y, x)
|
||||||
))
|
))
|
||||||
|
|
||||||
# We need to modify the CFG for min/max legalization.
|
# We need to modify the CFG for min/max legalization.
|
||||||
intel_expand.custom_legalize(insts.fmin, 'expand_minmax')
|
x86_expand.custom_legalize(insts.fmin, 'expand_minmax')
|
||||||
intel_expand.custom_legalize(insts.fmax, 'expand_minmax')
|
x86_expand.custom_legalize(insts.fmax, 'expand_minmax')
|
||||||
|
|
||||||
# Conversions from unsigned need special handling.
|
# Conversions from unsigned need special handling.
|
||||||
intel_expand.custom_legalize(insts.fcvt_from_uint, 'expand_fcvt_from_uint')
|
x86_expand.custom_legalize(insts.fcvt_from_uint, 'expand_fcvt_from_uint')
|
||||||
# Conversions from float to int can trap.
|
# Conversions from float to int can trap.
|
||||||
intel_expand.custom_legalize(insts.fcvt_to_sint, 'expand_fcvt_to_sint')
|
x86_expand.custom_legalize(insts.fcvt_to_sint, 'expand_fcvt_to_sint')
|
||||||
intel_expand.custom_legalize(insts.fcvt_to_uint, 'expand_fcvt_to_uint')
|
x86_expand.custom_legalize(insts.fcvt_to_uint, 'expand_fcvt_to_uint')
|
||||||
|
|
||||||
# Count leading and trailing zeroes, for baseline x86_64
|
# Count leading and trailing zeroes, for baseline x86_64
|
||||||
c_minus_one = Var('c_minus_one')
|
c_minus_one = Var('c_minus_one')
|
||||||
@@ -108,7 +108,7 @@ index1 = Var('index1')
|
|||||||
r2flags = Var('r2flags')
|
r2flags = Var('r2flags')
|
||||||
index2 = Var('index2')
|
index2 = Var('index2')
|
||||||
|
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.clz.i64(x),
|
a << insts.clz.i64(x),
|
||||||
Rtl(
|
Rtl(
|
||||||
c_minus_one << insts.iconst(imm64(-1)),
|
c_minus_one << insts.iconst(imm64(-1)),
|
||||||
@@ -118,7 +118,7 @@ intel_expand.legalize(
|
|||||||
a << insts.isub(c_sixty_three, index2),
|
a << insts.isub(c_sixty_three, index2),
|
||||||
))
|
))
|
||||||
|
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.clz.i32(x),
|
a << insts.clz.i32(x),
|
||||||
Rtl(
|
Rtl(
|
||||||
c_minus_one << insts.iconst(imm64(-1)),
|
c_minus_one << insts.iconst(imm64(-1)),
|
||||||
@@ -128,7 +128,7 @@ intel_expand.legalize(
|
|||||||
a << insts.isub(c_thirty_one, index2),
|
a << insts.isub(c_thirty_one, index2),
|
||||||
))
|
))
|
||||||
|
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.ctz.i64(x),
|
a << insts.ctz.i64(x),
|
||||||
Rtl(
|
Rtl(
|
||||||
c_sixty_four << insts.iconst(imm64(64)),
|
c_sixty_four << insts.iconst(imm64(64)),
|
||||||
@@ -136,7 +136,7 @@ intel_expand.legalize(
|
|||||||
a << insts.selectif(intcc.eq, r2flags, c_sixty_four, index1),
|
a << insts.selectif(intcc.eq, r2flags, c_sixty_four, index1),
|
||||||
))
|
))
|
||||||
|
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
a << insts.ctz.i32(x),
|
a << insts.ctz.i32(x),
|
||||||
Rtl(
|
Rtl(
|
||||||
c_thirty_two << insts.iconst(imm64(32)),
|
c_thirty_two << insts.iconst(imm64(32)),
|
||||||
@@ -164,7 +164,7 @@ qv16 = Var('qv16')
|
|||||||
qc77 = Var('qc77')
|
qc77 = Var('qc77')
|
||||||
qc0F = Var('qc0F')
|
qc0F = Var('qc0F')
|
||||||
qc01 = Var('qc01')
|
qc01 = Var('qc01')
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
qv16 << insts.popcnt.i64(qv1),
|
qv16 << insts.popcnt.i64(qv1),
|
||||||
Rtl(
|
Rtl(
|
||||||
qv3 << insts.ushr_imm(qv1, imm64(1)),
|
qv3 << insts.ushr_imm(qv1, imm64(1)),
|
||||||
@@ -204,7 +204,7 @@ lv16 = Var('lv16')
|
|||||||
lc77 = Var('lc77')
|
lc77 = Var('lc77')
|
||||||
lc0F = Var('lc0F')
|
lc0F = Var('lc0F')
|
||||||
lc01 = Var('lc01')
|
lc01 = Var('lc01')
|
||||||
intel_expand.legalize(
|
x86_expand.legalize(
|
||||||
lv16 << insts.popcnt.i32(lv1),
|
lv16 << insts.popcnt.i32(lv1),
|
||||||
Rtl(
|
Rtl(
|
||||||
lv3 << insts.ushr_imm(lv1, imm64(1)),
|
lv3 << insts.ushr_imm(lv1, imm64(1)),
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Intel Encoding recipes.
|
x86 Encoding recipes.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.isa import EncRecipe
|
from cdsl.isa import EncRecipe
|
||||||
@@ -31,7 +31,7 @@ except ImportError:
|
|||||||
# Opcode representation.
|
# Opcode representation.
|
||||||
#
|
#
|
||||||
# Cretonne requires each recipe to have a single encoding size in bytes, and
|
# Cretonne requires each recipe to have a single encoding size in bytes, and
|
||||||
# Intel opcodes are variable length, so we use separate recipes for different
|
# x86 opcodes are variable length, so we use separate recipes for different
|
||||||
# styles of opcodes and prefixes. The opcode format is indicated by the recipe
|
# styles of opcodes and prefixes. The opcode format is indicated by the recipe
|
||||||
# name prefix:
|
# name prefix:
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ class TailRecipe:
|
|||||||
"""
|
"""
|
||||||
Generate encoding recipes on demand.
|
Generate encoding recipes on demand.
|
||||||
|
|
||||||
Intel encodings are somewhat orthogonal with the opcode representation on
|
x86 encodings are somewhat orthogonal with the opcode representation on
|
||||||
one side and the ModR/M, SIB and immediate fields on the other side.
|
one side and the ModR/M, SIB and immediate fields on the other side.
|
||||||
|
|
||||||
A `TailRecipe` represents the part of an encoding that follow the opcode.
|
A `TailRecipe` represents the part of an encoding that follow the opcode.
|
||||||
@@ -144,7 +144,7 @@ class TailRecipe:
|
|||||||
|
|
||||||
The `emit` parameter contains Rust code to actually emit an encoding, like
|
The `emit` parameter contains Rust code to actually emit an encoding, like
|
||||||
`EncRecipe` does it. Additionally, the text `PUT_OP` is substituted with
|
`EncRecipe` does it. Additionally, the text `PUT_OP` is substituted with
|
||||||
the proper `put_*` function from the `intel/binemit.rs` module.
|
the proper `put_*` function from the `x86/binemit.rs` module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -590,7 +590,7 @@ fnaddr4 = TailRecipe(
|
|||||||
'fnaddr4', FuncAddr, size=4, ins=(), outs=GPR,
|
'fnaddr4', FuncAddr, size=4, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs4,
|
sink.reloc_external(Reloc::X86Abs4,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
0);
|
0);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -601,7 +601,7 @@ fnaddr8 = TailRecipe(
|
|||||||
'fnaddr8', FuncAddr, size=8, ins=(), outs=GPR,
|
'fnaddr8', FuncAddr, size=8, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs8,
|
sink.reloc_external(Reloc::X86Abs8,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
0);
|
0);
|
||||||
sink.put8(0);
|
sink.put8(0);
|
||||||
@@ -612,7 +612,7 @@ allones_fnaddr4 = TailRecipe(
|
|||||||
'allones_fnaddr4', FuncAddr, size=4, ins=(), outs=GPR,
|
'allones_fnaddr4', FuncAddr, size=4, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs4,
|
sink.reloc_external(Reloc::X86Abs4,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
0);
|
0);
|
||||||
// Write the immediate as `!0` for the benefit of BaldrMonkey.
|
// Write the immediate as `!0` for the benefit of BaldrMonkey.
|
||||||
@@ -624,7 +624,7 @@ allones_fnaddr8 = TailRecipe(
|
|||||||
'allones_fnaddr8', FuncAddr, size=8, ins=(), outs=GPR,
|
'allones_fnaddr8', FuncAddr, size=8, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs8,
|
sink.reloc_external(Reloc::X86Abs8,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
0);
|
0);
|
||||||
// Write the immediate as `!0` for the benefit of BaldrMonkey.
|
// Write the immediate as `!0` for the benefit of BaldrMonkey.
|
||||||
@@ -640,7 +640,7 @@ got_fnaddr8 = TailRecipe(
|
|||||||
modrm_riprel(out_reg0, sink);
|
modrm_riprel(out_reg0, sink);
|
||||||
// The addend adjusts for the difference between the end of the
|
// The addend adjusts for the difference between the end of the
|
||||||
// instruction and the beginning of the immediate field.
|
// instruction and the beginning of the immediate field.
|
||||||
sink.reloc_external(Reloc::IntelGOTPCRel4,
|
sink.reloc_external(Reloc::X86GOTPCRel4,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
-4);
|
-4);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -652,7 +652,7 @@ gvaddr4 = TailRecipe(
|
|||||||
'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR,
|
'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs4,
|
sink.reloc_external(Reloc::X86Abs4,
|
||||||
&func.global_vars[global_var].symbol_name(),
|
&func.global_vars[global_var].symbol_name(),
|
||||||
0);
|
0);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -663,7 +663,7 @@ gvaddr8 = TailRecipe(
|
|||||||
'gvaddr8', UnaryGlobalVar, size=8, ins=(), outs=GPR,
|
'gvaddr8', UnaryGlobalVar, size=8, ins=(), outs=GPR,
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
|
||||||
sink.reloc_external(Reloc::IntelAbs8,
|
sink.reloc_external(Reloc::X86Abs8,
|
||||||
&func.global_vars[global_var].symbol_name(),
|
&func.global_vars[global_var].symbol_name(),
|
||||||
0);
|
0);
|
||||||
sink.put8(0);
|
sink.put8(0);
|
||||||
@@ -677,7 +677,7 @@ got_gvaddr8 = TailRecipe(
|
|||||||
modrm_rm(5, out_reg0, sink);
|
modrm_rm(5, out_reg0, sink);
|
||||||
// The addend adjusts for the difference between the end of the
|
// The addend adjusts for the difference between the end of the
|
||||||
// instruction and the beginning of the immediate field.
|
// instruction and the beginning of the immediate field.
|
||||||
sink.reloc_external(Reloc::IntelGOTPCRel4,
|
sink.reloc_external(Reloc::X86GOTPCRel4,
|
||||||
&func.global_vars[global_var].symbol_name(),
|
&func.global_vars[global_var].symbol_name(),
|
||||||
-4);
|
-4);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -1009,7 +1009,7 @@ call_id = TailRecipe(
|
|||||||
PUT_OP(bits, BASE_REX, sink);
|
PUT_OP(bits, BASE_REX, sink);
|
||||||
// The addend adjusts for the difference between the end of the
|
// The addend adjusts for the difference between the end of the
|
||||||
// instruction and the beginning of the immediate field.
|
// instruction and the beginning of the immediate field.
|
||||||
sink.reloc_external(Reloc::IntelPCRel4,
|
sink.reloc_external(Reloc::X86PCRel4,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
-4);
|
-4);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -1019,7 +1019,7 @@ call_plt_id = TailRecipe(
|
|||||||
'call_plt_id', Call, size=4, ins=(), outs=(),
|
'call_plt_id', Call, size=4, ins=(), outs=(),
|
||||||
emit='''
|
emit='''
|
||||||
PUT_OP(bits, BASE_REX, sink);
|
PUT_OP(bits, BASE_REX, sink);
|
||||||
sink.reloc_external(Reloc::IntelPLTRel4,
|
sink.reloc_external(Reloc::X86PLTRel4,
|
||||||
&func.dfg.ext_funcs[func_ref].name,
|
&func.dfg.ext_funcs[func_ref].name,
|
||||||
-4);
|
-4);
|
||||||
sink.put4(0);
|
sink.put4(0);
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
Intel register banks.
|
x86 register banks.
|
||||||
|
|
||||||
While the floating-point registers are straight-forward, the general purpose
|
While the floating-point registers are straight-forward, the general purpose
|
||||||
register bank has a few quirks on Intel architectures. We have these encodings
|
register bank has a few quirks on x86. We have these encodings of the 8-bit
|
||||||
of the 8-bit registers:
|
registers:
|
||||||
|
|
||||||
I32 I64 | 16b 32b 64b
|
I32 I64 | 16b 32b 64b
|
||||||
000 AL AL | AX EAX RAX
|
000 AL AL | AX EAX RAX
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Intel settings.
|
x86 settings.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.settings import SettingGroup, BoolSetting, Preset
|
from cdsl.settings import SettingGroup, BoolSetting, Preset
|
||||||
@@ -7,7 +7,7 @@ from cdsl.predicates import And
|
|||||||
import base.settings as shared
|
import base.settings as shared
|
||||||
from .defs import ISA
|
from .defs import ISA
|
||||||
|
|
||||||
ISA.settings = SettingGroup('intel', parent=shared.group)
|
ISA.settings = SettingGroup('x86', parent=shared.group)
|
||||||
|
|
||||||
# The has_* settings here correspond to CPUID bits.
|
# The has_* settings here correspond to CPUID bits.
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ use_popcnt = And(has_popcnt, has_sse42)
|
|||||||
use_bmi1 = And(has_bmi1)
|
use_bmi1 = And(has_bmi1)
|
||||||
use_lzcnt = And(has_lzcnt)
|
use_lzcnt = And(has_lzcnt)
|
||||||
|
|
||||||
# Presets corresponding to Intel CPUs.
|
# Presets corresponding to x86 CPUs.
|
||||||
|
|
||||||
baseline = Preset()
|
baseline = Preset()
|
||||||
nehalem = Preset(
|
nehalem = Preset(
|
||||||
@@ -25,16 +25,16 @@ pub type Addend = i64;
|
|||||||
/// Relocation kinds for every ISA
|
/// Relocation kinds for every ISA
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Reloc {
|
pub enum Reloc {
|
||||||
/// Intel PC-relative 4-byte
|
/// x86 PC-relative 4-byte
|
||||||
IntelPCRel4,
|
X86PCRel4,
|
||||||
/// Intel absolute 4-byte
|
/// x86 absolute 4-byte
|
||||||
IntelAbs4,
|
X86Abs4,
|
||||||
/// Intel absolute 8-byte
|
/// x86 absolute 8-byte
|
||||||
IntelAbs8,
|
X86Abs8,
|
||||||
/// Intel GOT PC-relative 4-byte
|
/// x86 GOT PC-relative 4-byte
|
||||||
IntelGOTPCRel4,
|
X86GOTPCRel4,
|
||||||
/// Intel PLT-relative 4-byte
|
/// x86 PLT-relative 4-byte
|
||||||
IntelPLTRel4,
|
X86PLTRel4,
|
||||||
/// Arm32 call target
|
/// Arm32 call target
|
||||||
Arm32Call,
|
Arm32Call,
|
||||||
/// Arm64 call target
|
/// Arm64 call target
|
||||||
@@ -48,11 +48,11 @@ impl fmt::Display for Reloc {
|
|||||||
/// already unambigious, e.g. cton syntax with isa specified. In other contexts, use Debug.
|
/// already unambigious, e.g. cton syntax with isa specified. In other contexts, use Debug.
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Reloc::IntelPCRel4 => write!(f, "{}", "PCRel4"),
|
Reloc::X86PCRel4 => write!(f, "{}", "PCRel4"),
|
||||||
Reloc::IntelAbs4 => write!(f, "{}", "Abs4"),
|
Reloc::X86Abs4 => write!(f, "{}", "Abs4"),
|
||||||
Reloc::IntelAbs8 => write!(f, "{}", "Abs8"),
|
Reloc::X86Abs8 => write!(f, "{}", "Abs8"),
|
||||||
Reloc::IntelGOTPCRel4 => write!(f, "{}", "GOTPCRel4"),
|
Reloc::X86GOTPCRel4 => write!(f, "{}", "GOTPCRel4"),
|
||||||
Reloc::IntelPLTRel4 => write!(f, "{}", "PLTRel4"),
|
Reloc::X86PLTRel4 => write!(f, "{}", "PLTRel4"),
|
||||||
Reloc::Arm32Call | Reloc::Arm64Call | Reloc::RiscvCall => write!(f, "{}", "Call"),
|
Reloc::Arm32Call | Reloc::Arm64Call | Reloc::RiscvCall => write!(f, "{}", "Call"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Branch relaxation is the process of ensuring that all branches in the function have enough
|
//! Branch relaxation is the process of ensuring that all branches in the function have enough
|
||||||
//! range to encode their destination. It is common to have multiple branch encodings in an ISA.
|
//! range to encode their destination. It is common to have multiple branch encodings in an ISA.
|
||||||
//! For example, Intel branches can have either an 8-bit or a 32-bit displacement.
|
//! For example, x86 branches can have either an 8-bit or a 32-bit displacement.
|
||||||
//!
|
//!
|
||||||
//! On RISC architectures, it can happen that conditional branches have a shorter range than
|
//! On RISC architectures, it can happen that conditional branches have a shorter range than
|
||||||
//! unconditional branches:
|
//! unconditional branches:
|
||||||
|
|||||||
@@ -107,9 +107,8 @@ pub struct StackSlotData {
|
|||||||
|
|
||||||
/// Offset of stack slot relative to the stack pointer in the caller.
|
/// Offset of stack slot relative to the stack pointer in the caller.
|
||||||
///
|
///
|
||||||
/// On Intel ISAs, the base address is the stack pointer *before* the return address was
|
/// On x86, the base address is the stack pointer *before* the return address was pushed. On
|
||||||
/// pushed. On RISC ISAs, the base address is the value of the stack pointer on entry to the
|
/// RISC ISAs, the base address is the value of the stack pointer on entry to the function.
|
||||||
/// function.
|
|
||||||
///
|
///
|
||||||
/// For `OutgoingArg` stack slots, the offset is relative to the current function's stack
|
/// For `OutgoingArg` stack slots, the offset is relative to the current function's stack
|
||||||
/// pointer immediately before the call.
|
/// pointer immediately before the call.
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ impl RecipeConstraints {
|
|||||||
/// The origin depends on the ISA and the specific instruction:
|
/// The origin depends on the ISA and the specific instruction:
|
||||||
///
|
///
|
||||||
/// - RISC-V and ARM Aarch64 use the address of the branch instruction, `origin = 0`.
|
/// - RISC-V and ARM Aarch64 use the address of the branch instruction, `origin = 0`.
|
||||||
/// - Intel uses the address of the instruction following the branch, `origin = 2` for a 2-byte
|
/// - x86 uses the address of the instruction following the branch, `origin = 2` for a 2-byte
|
||||||
/// branch instruction.
|
/// branch instruction.
|
||||||
/// - ARM's A32 encoding uses the address of the branch instruction + 8 bytes, `origin = 8`.
|
/// - ARM's A32 encoding uses the address of the branch instruction + 8 bytes, `origin = 8`.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ use timing;
|
|||||||
#[cfg(build_riscv)]
|
#[cfg(build_riscv)]
|
||||||
mod riscv;
|
mod riscv;
|
||||||
|
|
||||||
#[cfg(build_intel)]
|
#[cfg(build_x86)]
|
||||||
mod intel;
|
mod x86;
|
||||||
|
|
||||||
#[cfg(build_arm32)]
|
#[cfg(build_arm32)]
|
||||||
mod arm32;
|
mod arm32;
|
||||||
@@ -95,7 +95,7 @@ macro_rules! isa_builder {
|
|||||||
pub fn lookup(name: &str) -> Result<Builder, LookupError> {
|
pub fn lookup(name: &str) -> Result<Builder, LookupError> {
|
||||||
match name {
|
match name {
|
||||||
"riscv" => isa_builder!(riscv, build_riscv),
|
"riscv" => isa_builder!(riscv, build_riscv),
|
||||||
"intel" => isa_builder!(intel, build_intel),
|
"x86" => isa_builder!(x86, build_x86),
|
||||||
"arm32" => isa_builder!(arm32, build_arm32),
|
"arm32" => isa_builder!(arm32, build_arm32),
|
||||||
"arm64" => isa_builder!(arm64, build_arm64),
|
"arm64" => isa_builder!(arm64, build_arm64),
|
||||||
_ => Err(LookupError::Unknown),
|
_ => Err(LookupError::Unknown),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Intel ABI implementation.
|
//! x86 ABI implementation.
|
||||||
|
|
||||||
use super::registers::{FPR, GPR, RU};
|
use super::registers::{FPR, GPR, RU};
|
||||||
use abi::{legalize_args, ArgAction, ArgAssigner, ValueConversion};
|
use abi::{legalize_args, ArgAction, ArgAssigner, ValueConversion};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Emitting binary Intel machine code.
|
//! Emitting binary x86 machine code.
|
||||||
|
|
||||||
use super::registers::RU;
|
use super::registers::RU;
|
||||||
use binemit::{bad_encoding, CodeSink, Reloc};
|
use binemit::{bad_encoding, CodeSink, Reloc};
|
||||||
@@ -7,7 +7,7 @@ use ir::{Ebb, Function, Inst, InstructionData, Opcode, TrapCode};
|
|||||||
use isa::{RegUnit, StackBase, StackBaseMask, StackRef};
|
use isa::{RegUnit, StackBase, StackBaseMask, StackRef};
|
||||||
use regalloc::RegDiversions;
|
use regalloc::RegDiversions;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/binemit-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/binemit-x86.rs"));
|
||||||
|
|
||||||
// Convert a stack base to the corresponding register.
|
// Convert a stack base to the corresponding register.
|
||||||
fn stk_base(base: StackBase) -> RegUnit {
|
fn stk_base(base: StackBase) -> RegUnit {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Encoding tables for Intel ISAs.
|
//! Encoding tables for x86 ISAs.
|
||||||
|
|
||||||
use super::registers::*;
|
use super::registers::*;
|
||||||
use bitset::BitSet;
|
use bitset::BitSet;
|
||||||
@@ -12,8 +12,8 @@ use isa::enc_tables::*;
|
|||||||
use isa::encoding::RecipeSizing;
|
use isa::encoding::RecipeSizing;
|
||||||
use predicates;
|
use predicates;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/encoding-x86.rs"));
|
||||||
include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/legalize-x86.rs"));
|
||||||
|
|
||||||
/// Expand the `sdiv` and `srem` instructions using `x86_sdivmodx`.
|
/// Expand the `sdiv` and `srem` instructions using `x86_sdivmodx`.
|
||||||
fn expand_sdivrem(
|
fn expand_sdivrem(
|
||||||
@@ -147,7 +147,7 @@ fn expand_udivrem(
|
|||||||
pos.remove_inst();
|
pos.remove_inst();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expand the `fmin` and `fmax` instructions using the Intel `x86_fmin` and `x86_fmax`
|
/// Expand the `fmin` and `fmax` instructions using the x86 `x86_fmin` and `x86_fmax`
|
||||||
/// instructions.
|
/// instructions.
|
||||||
fn expand_minmax(
|
fn expand_minmax(
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
@@ -241,7 +241,7 @@ fn expand_minmax(
|
|||||||
cfg.recompute_ebb(pos.func, done);
|
cfg.recompute_ebb(pos.func, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Intel has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to
|
/// x86 has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to
|
||||||
/// i64 with a pattern, the rest needs more code.
|
/// i64 with a pattern, the rest needs more code.
|
||||||
fn expand_fcvt_from_uint(
|
fn expand_fcvt_from_uint(
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Intel Instruction Set Architectures.
|
//! x86 Instruction Set Architectures.
|
||||||
|
|
||||||
mod abi;
|
mod abi;
|
||||||
mod binemit;
|
mod binemit;
|
||||||
@@ -25,7 +25,7 @@ struct Isa {
|
|||||||
cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
|
cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an ISA builder for creating Intel targets.
|
/// Get an ISA builder for creating x86 targets.
|
||||||
pub fn isa_builder() -> IsaBuilder {
|
pub fn isa_builder() -> IsaBuilder {
|
||||||
IsaBuilder {
|
IsaBuilder {
|
||||||
setup: settings::builder(),
|
setup: settings::builder(),
|
||||||
@@ -51,7 +51,7 @@ fn isa_constructor(
|
|||||||
|
|
||||||
impl TargetIsa for Isa {
|
impl TargetIsa for Isa {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"intel"
|
"x86"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> &shared_settings::Flags {
|
fn flags(&self) -> &shared_settings::Flags {
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
//! Intel register descriptions.
|
//! x86 register descriptions.
|
||||||
|
|
||||||
use isa::registers::{RegBank, RegClass, RegClassData, RegInfo, RegUnit};
|
use isa::registers::{RegBank, RegClass, RegClassData, RegInfo, RegUnit};
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/registers-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/registers-x86.rs"));
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
//! Intel Settings.
|
//! x86 Settings.
|
||||||
|
|
||||||
use settings::{self, detail, Builder};
|
use settings::{self, detail, Builder};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
// Include code generated by `lib/cretonne/meta/gen_settings.py`. This file contains a public
|
// Include code generated by `lib/cretonne/meta/gen_settings.py`. This file contains a public
|
||||||
// `Flags` struct with an impl for all of the settings defined in
|
// `Flags` struct with an impl for all of the settings defined in
|
||||||
// `lib/cretonne/meta/isa/intel/settings.py`.
|
// `lib/cretonne/meta/isa/x86/settings.py`.
|
||||||
include!(concat!(env!("OUT_DIR"), "/settings-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/settings-x86.rs"));
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -196,7 +196,7 @@ impl<'a> fmt::Display for DisplayRegisterSet<'a> {
|
|||||||
}
|
}
|
||||||
// Display individual registers as either the second letter of their
|
// Display individual registers as either the second letter of their
|
||||||
// name or the last digit of their number.
|
// name or the last digit of their number.
|
||||||
// This works for Intel (rax, rbx, ...) and for numbered regs.
|
// This works for x86 (rax, rbx, ...) and for numbered regs.
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pub fn builders() -> Result<(settings::Builder, isa::Builder), &'static str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let name = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
let name = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
||||||
"intel"
|
"x86"
|
||||||
} else if cfg!(target_arch = "arm") {
|
} else if cfg!(target_arch = "arm") {
|
||||||
"arm32"
|
"arm32"
|
||||||
} else if cfg!(target_arch = "aarch64") {
|
} else if cfg!(target_arch = "aarch64") {
|
||||||
|
|||||||
Reference in New Issue
Block a user