forked from bytecodealliance/cranelift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
227 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
; Binary emission. | ||
test binemit | ||
isa arm64 | ||
|
||
; The binary encodings can be verified with the command: | ||
; | ||
; sed -ne 's/^ *; asm: *//p' filetests/isa/arm64/binary.cton | llvm-mc -show-encoding -triple=arm64 | ||
; | ||
|
||
function %RV32I(i32 link [%x1]) -> i32 link [%x1] { | ||
fn0 = function %foo() | ||
sig0 = () | ||
|
||
ebb0(v9999: i32): | ||
; asm: mov w2, #1 | ||
[-,%x2] v1 = iconst.i32 1 ; bin: 52800022 | ||
; asm: mov x3, #2 | ||
[-,%x3] v2 = iconst.i64 2 ; bin: d2800043 | ||
return v1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
""" | ||
ARM64 Encodings. | ||
""" | ||
from __future__ import absolute_import | ||
from base import instructions as base | ||
from base.immediates import intcc | ||
|
||
from .defs import A64 | ||
from .recipes import MOVZ | ||
from .recipes import Move16 | ||
|
||
from cdsl.ast import Var | ||
from base.legalize import narrow, expand | ||
|
||
# TODO what does this control? | ||
A64.legalize_monomorphic(expand) | ||
A64.legalize_type( | ||
default=narrow, | ||
i32=expand, | ||
i64=expand, | ||
f32=expand, | ||
f64=expand) | ||
|
||
# Dummies for instruction predicates. | ||
x = Var('x') | ||
y = Var('y') | ||
dest = Var('dest') | ||
args = Var('args') | ||
|
||
# Small constants (16 bits). | ||
A64.enc(base.iconst.i32, Move16, MOVZ(is64bits=0b0)) | ||
A64.enc(base.iconst.i64, Move16, MOVZ(is64bits=0b1)) | ||
|
||
# Integer constants with the low 12 bits clear are materialized by lui. | ||
# A64.enc(base.iconst.i32, U, LUI()) | ||
# A64.enc(base.iconst.i64, U, LUI()) | ||
|
||
# # Basic arithmetic binary instructions are encoded in an R-type instruction. | ||
# for inst, inst_imm, f3, f7 in [ | ||
# (base.iadd, base.iadd_imm, 0b000, 0b0000000), | ||
# (base.isub, None, 0b000, 0b0100000), | ||
# (base.bxor, base.bxor_imm, 0b100, 0b0000000), | ||
# (base.bor, base.bor_imm, 0b110, 0b0000000), | ||
# (base.band, base.band_imm, 0b111, 0b0000000) | ||
# ]: | ||
# A64.enc(inst.i64, R, OP(f3, f7)) | ||
|
||
# # Immediate versions for add/xor/or/and. | ||
# if inst_imm: | ||
# A64.enc(inst_imm.i64, Ii, OPIMM(f3)) | ||
|
||
# # 32-bit ops in A64. | ||
# A64.enc(base.iadd.i32, R, OP32(0b000, 0b0000000)) | ||
# A64.enc(base.isub.i32, R, OP32(0b000, 0b0100000)) | ||
# # There are no andiw/oriw/xoriw variations. | ||
# A64.enc(base.iadd_imm.i32, Ii, OPIMM32(0b000)) | ||
|
||
# # Dynamic shifts have the same masking semantics as the cton base instructions. | ||
# for inst, inst_imm, f3, f7 in [ | ||
# (base.ishl, base.ishl_imm, 0b001, 0b0000000), | ||
# (base.ushr, base.ushr_imm, 0b101, 0b0000000), | ||
# (base.sshr, base.sshr_imm, 0b101, 0b0100000), | ||
# ]: | ||
|
||
# A64.enc(inst.i64.i64, R, OP(f3, f7)) | ||
# A64.enc(inst.i32.i32, R, OP32(f3, f7)) | ||
# # Allow i32 shift amounts in 64-bit shifts. | ||
# A64.enc(inst.i64.i32, R, OP(f3, f7)) | ||
# A64.enc(inst.i32.i64, R, OP32(f3, f7)) | ||
|
||
# # Immediate shifts. | ||
|
||
# A64.enc(inst_imm.i64, Rshamt, OPIMM(f3, f7)) | ||
# A64.enc(inst_imm.i32, Rshamt, OPIMM32(f3, f7)) | ||
|
||
# # Signed and unsigned integer 'less than'. There are no 'w' variants for | ||
# # comparing 32-bit numbers in A64. | ||
|
||
# A64.enc(base.icmp.i64(intcc.slt, x, y), Ricmp, OP(0b010, 0b0000000)) | ||
|
||
# A64.enc(base.icmp.i64(intcc.ult, x, y), Ricmp, OP(0b011, 0b0000000)) | ||
|
||
|
||
# A64.enc(base.icmp_imm.i64(intcc.slt, x, y), Iicmp, OPIMM(0b010)) | ||
|
||
# A64.enc(base.icmp_imm.i64(intcc.ult, x, y), Iicmp, OPIMM(0b011)) | ||
|
||
# # Control flow. | ||
|
||
# # Unconditional branches. | ||
|
||
# A64.enc(base.jump, UJ, JAL()) | ||
|
||
# A64.enc(base.call, UJcall, JAL()) | ||
|
||
# # Conditional branches. | ||
# for cond, f3 in [ | ||
# (intcc.eq, 0b000), | ||
# (intcc.ne, 0b001), | ||
# (intcc.slt, 0b100), | ||
# (intcc.sge, 0b101), | ||
# (intcc.ult, 0b110), | ||
# (intcc.uge, 0b111) | ||
# ]: | ||
|
||
# A64.enc(base.br_icmp.i64(cond, x, y, dest, args), SB, BRANCH(f3)) | ||
|
||
# for inst, f3 in [ | ||
# (base.brz, 0b000), | ||
# (base.brnz, 0b001) | ||
# ]: | ||
|
||
# A64.enc(inst.i64, SBzero, BRANCH(f3)) | ||
|
||
# A64.enc(inst.b1, SBzero, BRANCH(f3)) | ||
|
||
# # Returns are a special case of JALR using %x1 to hold the return address. | ||
# # The return address is provided by a special-purpose `link` return value that | ||
# # is added by legalize_signature(). | ||
|
||
# A64.enc(base.x_return, Iret, JALR()) | ||
|
||
# A64.enc(base.call_indirect.i64, Icall, JALR()) | ||
|
||
# # Spill and fill. | ||
|
||
# A64.enc(base.spill.i32, GPsp, STORE(0b010)) | ||
# A64.enc(base.spill.i64, GPsp, STORE(0b011)) | ||
|
||
# A64.enc(base.fill.i32, GPfi, LOAD(0b010)) | ||
# A64.enc(base.fill.i64, GPfi, LOAD(0b011)) | ||
|
||
# # Register copies. | ||
|
||
# A64.enc(base.copy.i64, Icopy, OPIMM(0b000)) | ||
# A64.enc(base.copy.i32, Icopy, OPIMM32(0b000)) | ||
|
||
# A64.enc(base.regmove.i64, Irmov, OPIMM(0b000)) | ||
# A64.enc(base.regmove.i32, Irmov, OPIMM32(0b000)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
""" | ||
ARM64 Encoding recipes. | ||
The encoding recipes defined here correspond to the ARM64 native instruction | ||
formats described in the reference. | ||
""" | ||
from __future__ import absolute_import | ||
from cdsl.isa import EncRecipe | ||
from cdsl.predicates import IsSignedInt | ||
from cdsl.registers import Stack | ||
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm | ||
from base.formats import Unary, UnaryImm, BranchIcmp, Branch, Jump | ||
from base.formats import Call, IndirectCall, RegMove | ||
from .registers import GPR, FPR, FLAG | ||
|
||
def dataProcessing(op0): | ||
assert op0 <= 0b111 | ||
return (0b100 << 26) | (op0 << 23) | ||
|
||
def moveWide(is64bits, opc): | ||
assert is64bits <= 0b1 | ||
assert opc <= 0b11 | ||
return ((is64bits << 31) | (opc << 29) | dataProcessing(0b101)) >> 23 | ||
|
||
def MOVN(is64bits): | ||
return moveWide(is64bits, 0b00) | ||
def MOVZ(is64bits): | ||
return moveWide(is64bits, 0b10) | ||
def MOVK(is64bits): | ||
return moveWide(is64bits, 0b11) | ||
|
||
Move16 = EncRecipe( | ||
'Move16', UnaryImm, size=4, ins=(), outs=GPR, | ||
# TODO the predicate could be more precise: has <= 16 adjacent non-zero bits | ||
instp=IsSignedInt(UnaryImm.imm, 16), | ||
emit='put_move(bits, imm.into(), out_reg0, sink);') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,33 @@ | ||
//! Emitting binary ARM64 machine code. | ||
|
||
use binemit::{CodeSink, bad_encoding}; | ||
use ir::{Function, Inst}; | ||
use ir::{Function, Inst, InstructionData}; | ||
use isa::{RegUnit, StackRef, StackBaseMask}; | ||
use regalloc::RegDiversions; | ||
|
||
include!(concat!(env!("OUT_DIR"), "/binemit-arm64.rs")); | ||
|
||
pub static RELOC_NAMES: [&'static str; 1] = ["Call"]; | ||
|
||
/// Move instruction. | ||
/// | ||
/// 31 22 20 4 | ||
/// bits hw imm16 Rd | ||
/// 23 21 5 0 | ||
fn put_move<CS: CodeSink + ?Sized>(bits: u16, imm: i64, rd: RegUnit, sink: &mut CS) { | ||
let rd = u32::from(rd) & 0x1f; | ||
|
||
let mut i: u32 = rd; | ||
assert!(imm <= 0xffff); | ||
i |= (imm as u32) << 5; | ||
|
||
// TODO shifts are not handled here... yet. | ||
let shift = 0; | ||
assert!(shift <= 48 && shift % 16 == 0); | ||
let hw = shift / 16; | ||
|
||
i |= hw << 21; | ||
i |= (bits as u32) << 23; | ||
|
||
sink.put4(i); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters