Commit 9e67a38d authored by Javad Ebrahimian Amiri's avatar Javad Ebrahimian Amiri

Merge branch 'rtmu-dev' into 'master'

rtmu dev

See merge request !59
parents 6f647556 c6557f98
......@@ -7,20 +7,26 @@ stages:
before_script:
- export MU_ZEBU=$CI_PROJECT_DIR
- export ZEBU_BUILD=release
- export ZEBU_CARGO_ARG="--release"
- export CARGO_HOME=.cargo
- export CC=clang
- export CXX=clang++
- export RUST_TEST_THREADS=1
- export LD_LIBRARY_PATH=$MU_ZEBU/target/$ZEBU_BUILD/deps/:$LD_LIBRARY_PATH
- export PYTHONPATH=mu-client-pypy
- source /home/gitlab-runner/ci/bin/activate
build:
stage: build
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo clean
- time rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test -j6 --release --no-run --color=always
- rustc --version
- cargo clean
- time cargo test -j6 $ZEBU_CARGO_ARG --no-run --color=always
artifacts:
paths:
- target/debug/deps/libmu.so
- target/debug/deps/libmu.a
- target/debug/deps/lib-*
- target/release/deps/libmu.so
- target/release/deps/libmu.a
- target/release/deps/lib-*
......@@ -28,22 +34,22 @@ build:
test:cargo:api:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_api --release 2> /dev/null
- cargo test test_api $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:ir:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_ir --release 2> /dev/null
- cargo test test_ir $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:compiler:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_compiler --release 2> /dev/null
- cargo test test_compiler $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:runtime:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_runtime --release 2> /dev/null
- cargo test test_runtime $ZEBU_CARGO_ARG 2> /dev/null
.build_muc: &build_muc |
if [ -d "tests/test_muc/mu-tool-compiler" ]; then rm -Rf tests/test_muc/mu-tool-compiler; fi
......@@ -53,7 +59,7 @@ test:cargo:runtime:
export ANTLR_HOME=/home/gitlab-runner/antlr4/runtime/Cpp/run
mkdir lib
cp -r $ANTLR_HOME/usr/local/lib/* $PWD/lib/
cp -r $MU_ZEBU/target/release/deps/* $PWD/lib/
cp -r $MU_ZEBU/target/$ZEBU_BUILD/deps/* $PWD/lib/
export CC=clang
export CXX=clang++
make
......@@ -159,7 +165,7 @@ testjit:som:
mubench:
stage: mubench
script:
- cp ./target/release/deps/libmu.so ./target/release/libmu.so
- cp $MU_ZEBU/target/$ZEBU_BUILD/deps/libmu.so ./target/$ZEBU_BUILD/libmu.so
- deactivate
- git clone https://gitlab.anu.edu.au/mu/mu-perf-benchmarks.git
- git clone https://gitlab.anu.edu.au/mu/mu-client-pypy.git
......@@ -179,3 +185,4 @@ rustfmt:
stage: rustfmt
script:
- cargo-fmt -- --check --verbose -- src/lib.rs src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs
allow_failure: true
......@@ -15,7 +15,7 @@
[package]
name = "mu"
version = "0.0.1"
authors = [ "Your name <you@example.com>" ]
authors = [ "Your name <you@example.com>", "Javad Amiri <javad.amiri@anu.edu.au>" ]
build = "build.rs"
[lib]
......@@ -26,6 +26,7 @@ doctest = false
default = ["aot"]
aot = []
jit = []
realtime = ["mu_ast/realtime", "mu_utils/realtime", "mu_gc/realtime"]
[build-dependencies]
cc = "*"
......@@ -34,7 +35,7 @@ built = "*"
[dependencies]
mu_ast = {path = "src/ast"}
mu_utils = {path = "src/utils"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc="*"
field-offset = "*"
......@@ -46,7 +47,8 @@ num = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
serde = "*"
serde = { version = "*", features = ["derive"]}
bincode = "*"
serde_derive = "*"
time = "*"
maplit = "*"
......@@ -56,3 +58,4 @@ extprim = "*"
num-traits = "*"
built = "*"
mu_gc = { path = "src/gc"}
cfg-if = "*"
......@@ -53,5 +53,6 @@ fn main() {
}
fn built() {
built::write_built_file().expect("Failed to acquire build-time information");
built::write_built_file()
.expect("Failed to acquire build-time information");
}
#trailing_comma = "Never"
max_width = 80
wrap_comments = true
trailing_comma = "Never"
......@@ -15,16 +15,22 @@
[package]
name = "mu_ast"
version = "0.0.1"
authors = ["qinsoon <qinsoon@gmail.com>"]
authors = ["qinsoon <qinsoon@gmail.com>", "Javad Amiri <javad.amiri@anu.edu.au>"]
[features]
realtime = []
[lib]
crate-type = ["rlib"]
[build-dependencies]
log = "*"
[dependencies]
mu_utils = {path = "../utils"}
lazy_static = "0.2.11"
log = "*"
simple_logger = "*"
regex = "0.2.2"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
#rodal = { path = "../../rodal", version = "*" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc = "*"
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
......@@ -14,7 +14,8 @@
//! # MuIR AST crate
//!
//! This crate provides data structures to allow construct MuIR in Rust code, including:
//! This crate provides data structures to allow construct MuIR in Rust code,
//! including:
//!
//! * types
//! * ir
......@@ -78,3 +79,9 @@ pub mod inst;
pub mod op;
pub mod ptr;
pub mod types;
#[cfg(feature = "realtime")]
pub mod ir_rt;
#[cfg(all(feature = "realtime", target_os = "linux"))]
pub mod ir_rt_posix;
......@@ -36,7 +36,7 @@ pub enum BinOp {
FSub,
FMul,
FDiv,
FRem,
FRem
}
impl fmt::Display for BinOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
......@@ -49,7 +49,7 @@ impl BinOp {
use op::BinOp::*;
match self {
FAdd | FSub | FMul | FDiv | FRem => true,
_ => false,
_ => false
}
}
}
......@@ -83,7 +83,7 @@ pub enum CmpOp {
FULT,
FULE,
FUNE,
FUNO,
FUNO
}
impl fmt::Display for CmpOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
......@@ -92,7 +92,8 @@ impl fmt::Display for CmpOp {
}
impl CmpOp {
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to (b X a)
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to (b X
/// a)
pub fn swap_operands(self) -> CmpOp {
use op::CmpOp::*;
match self {
......@@ -116,11 +117,12 @@ impl CmpOp {
FUGT => FULT,
FULT => FUGT,
_ => self, // all other comparisons are symmetric
_ => self // all other comparisons are symmetric
}
}
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to NOT(a X b)
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to
/// NOT(a X b)
pub fn invert(self) -> CmpOp {
use op::CmpOp::*;
match self {
......@@ -161,7 +163,7 @@ impl CmpOp {
FONE => FUEQ,
FFALSE => FTRUE,
FTRUE => FFALSE,
FTRUE => FFALSE
}
}
......@@ -173,7 +175,7 @@ impl CmpOp {
SLT => ULT,
SGT => UGT,
SLE => ULE,
_ => self,
_ => self
}
}
......@@ -181,7 +183,7 @@ impl CmpOp {
use op::CmpOp::*;
match self {
SGE | SLT | SGT | SLE => true,
_ => false,
_ => false
}
}
......@@ -189,7 +191,7 @@ impl CmpOp {
use op::CmpOp::*;
match self {
EQ | NE | SGE | SGT | SLE | SLT | UGE | UGT | ULE | ULT => true,
_ => false,
_ => false
}
}
......@@ -200,14 +202,14 @@ impl CmpOp {
use op::CmpOp::*;
match self {
EQ | NE => true,
_ => false,
_ => false
}
}
pub fn is_ult_cmp(self) -> bool {
use op::CmpOp::*;
match self {
UGE | UGT | ULE | ULT => true,
_ => false,
_ => false
}
}
......@@ -215,7 +217,7 @@ impl CmpOp {
use op::CmpOp::*;
match self {
EQ | NE | FORD | FUNO | FUNE | FUEQ | FONE | FOEQ => true,
_ => false,
_ => false
}
}
}
......@@ -233,7 +235,7 @@ pub enum ConvOp {
SITOFP,
BITCAST,
REFCAST,
PTRCAST,
PTRCAST
}
impl fmt::Display for ConvOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
......@@ -253,7 +255,7 @@ pub enum AtomicRMWOp {
MAX,
MIN,
UMAX,
UMIN,
UMIN
}
impl fmt::Display for AtomicRMWOp {
......
......@@ -14,7 +14,8 @@
use std::sync::Arc;
/// P<T> is alias type for sharable Mu AST components (such as Value, MuFuncSig, MuType, etc)
/// P<T> is alias type for sharable Mu AST components (such as Value, MuFuncSig,
/// MuType, etc)
// This design is similar to P<T> in rustc compiler.
// However, instead of using Box<T>, we use Arc<T> to encourage sharing
pub type P<T> = Arc<T>;
......
This diff is collapsed.
This diff is collapsed.
......@@ -12,7 +12,7 @@ pub enum CallConvResult {
GPR(P<Value>),
GPREX(P<Value>, P<Value>),
FPR(P<Value>),
STACK,
STACK
}
pub mod mu {
......@@ -55,10 +55,12 @@ pub mod c {
ret.push(CallConvResult::STACK);
}
} else if arg_reg_group == RegGroup::GPREX {
// need two regsiters for this, otherwise, we need to pass on stack
// need two regsiters for this, otherwise, we need to pass on
// stack
if gpr_arg_count + 1 < x86_64::ARGUMENT_GPRS.len() {
let arg_gpr1 = x86_64::ARGUMENT_GPRS[gpr_arg_count].clone();
let arg_gpr2 = x86_64::ARGUMENT_GPRS[gpr_arg_count + 1].clone();
let arg_gpr2 =
x86_64::ARGUMENT_GPRS[gpr_arg_count + 1].clone();
ret.push(CallConvResult::GPREX(arg_gpr1, arg_gpr2));
gpr_arg_count += 2;
......@@ -83,7 +85,10 @@ pub mod c {
ret
}
pub fn compute_stack_args(tys: &Vec<P<MuType>>, vm: &VM) -> (ByteSize, Vec<ByteSize>) {
pub fn compute_stack_args(
tys: &Vec<P<MuType>>,
vm: &VM
) -> (ByteSize, Vec<ByteSize>) {
let callconv = compute_arguments(tys);
let mut stack_arg_tys = vec![];
......@@ -124,7 +129,8 @@ pub mod c {
} else if RegGroup::get_from_ty(ty) == RegGroup::GPREX {
if gpr_ret_count + 1 < x86_64::RETURN_GPRS.len() {
let ret_gpr1 = x86_64::RETURN_GPRS[gpr_ret_count].clone();
let ret_gpr2 = x86_64::RETURN_GPRS[gpr_ret_count + 1].clone();
let ret_gpr2 =
x86_64::RETURN_GPRS[gpr_ret_count + 1].clone();
ret.push(CallConvResult::GPREX(ret_gpr1, ret_gpr2));
} else {
......@@ -149,14 +155,19 @@ pub mod c {
ret
}
pub fn compute_stack_retvals(tys: &Vec<P<MuType>>, vm: &VM) -> (ByteSize, Vec<ByteSize>) {
pub fn compute_stack_retvals(
tys: &Vec<P<MuType>>,
vm: &VM
) -> (ByteSize, Vec<ByteSize>) {
let callconv = compute_return_values(tys);
let mut stack_ret_val_tys = vec![];
for i in 0..callconv.len() {
let ref cc = callconv[i];
match cc {
&CallConvResult::STACK => stack_ret_val_tys.push(tys[i].clone()),
&CallConvResult::STACK => {
stack_ret_val_tys.push(tys[i].clone())
}
_ => {}
}
}
......@@ -164,11 +175,11 @@ pub mod c {
compute_stack_locations(&stack_ret_val_tys, vm)
}
/// computes the area on the stack for a list of types that need to put on stack,
/// returns a tuple of (size, offset for each values on stack)
/// computes the area on the stack for a list of types that need to put on
/// stack, returns a tuple of (size, offset for each values on stack)
pub fn compute_stack_locations(
stack_val_tys: &Vec<P<MuType>>,
vm: &VM,
vm: &VM
) -> (ByteSize, Vec<ByteSize>) {
let (stack_arg_size, _, stack_arg_offsets) =
BackendType::sequential_layout(stack_val_tys, vm);
......@@ -176,7 +187,8 @@ pub mod c {
// "The end of the input argument area shall be aligned on a 16
// (32, if __m256 is passed on stack) byte boundary." - x86 ABI
// if we need to special align the args, we do it now
// (then the args will be put to stack following their regular alignment)
// (then the args will be put to stack following their regular
// alignment)
let mut stack_arg_size_with_padding = stack_arg_size;
if stack_arg_size % 16 == 0 {
......
......@@ -19,17 +19,21 @@ use runtime::ValueLocation;
use compiler::backend::{Mem, Reg};
use compiler::machine_code::MachineCode;
/// CodeGenerator provides an interface to emit x86_64 code for instruction selection.
/// This allows us to implement the other parts of the compiler (mostly instruction selection)
/// without assuming code generator. Currently there is only an assembly backend
/// that implements this interface for ahead-of-time compilation. We plan to add
/// a binary backend for just-in-time compilation.
/// CodeGenerator provides an interface to emit x86_64 code for instruction
/// selection. This allows us to implement the other parts of the compiler
/// (mostly instruction selection) without assuming code generator. Currently
/// there is only an assembly backend that implements this interface for
/// ahead-of-time compilation. We plan to add a binary backend for just-in-time
/// compilation.
pub trait CodeGenerator {
/// starts code for a function
fn start_code(&mut self, func_name: MuName, entry: MuName) -> ValueLocation;
fn start_code(&mut self, func_name: MuName, entry: MuName)
-> ValueLocation;
/// finishes code for a function
fn finish_code(&mut self, func_name: MuName)
-> (Box<MachineCode + Sync + Send>, ValueLocation);
fn finish_code(
&mut self,
func_name: MuName
) -> (Box<MachineCode + Sync + Send>, ValueLocation);
/// starts a sequence of linear code (no branch)
fn start_code_sequence(&mut self);
......@@ -43,7 +47,8 @@ pub trait CodeGenerator {
fn start_block(&mut self, block_name: MuName);
/// starts an exceptional block, and returns its code address
fn start_exception_block(&mut self, block_name: MuName) -> ValueLocation;
/// finishes a block (must have called start_block() or start_excpetion_block() first)
/// finishes a block (must have called start_block() or
/// start_excpetion_block() first)
fn end_block(&mut self, block_name: MuName);
// adds CFI info
......@@ -238,7 +243,7 @@ pub trait CodeGenerator {
pe: Option<MuName>,
uses: Vec<P<Value>>,
defs: Vec<P<Value>>,
is_native: bool,
is_native: bool
) -> ValueLocation;
fn emit_call_near_r64(
&mut self,
......@@ -246,7 +251,7 @@ pub trait CodeGenerator {
func: &P<Value>,
pe: Option<MuName>,
uses: Vec<P<Value>>,
defs: Vec<P<Value>>,
defs: Vec<P<Value>>
) -> ValueLocation;
fn emit_call_near_mem64(
&mut self,
......@@ -254,7 +259,7 @@ pub trait CodeGenerator {
func: &P<Value>,
pe: Option<MuName>,
uses: Vec<P<Value>>,
defs: Vec<P<Value>>,
defs: Vec<P<Value>>
) -> ValueLocation;
// sometimes we use jmp as a call (but without pushing return address)
......@@ -265,7 +270,7 @@ pub trait CodeGenerator {
pe: Option<MuName>,
uses: Vec<P<Value>>,
defs: Vec<P<Value>>,
is_native: bool,
is_native: bool
) -> ValueLocation;
fn emit_call_jmp_indirect(
&mut self,
......@@ -273,7 +278,7 @@ pub trait CodeGenerator {
func: &P<Value>,
pe: Option<MuName>,
uses: Vec<P<Value>>,
defs: Vec<P<Value>>,
defs: Vec<P<Value>>
) -> ValueLocation;
fn emit_ret(&mut self);
......
</
......@@ -18,8 +18,9 @@
pub mod inst_sel;
mod codegen;
/// CodeGenerator trait serves as an interface to the backend code generator, which
/// may generate assembly code or binary (not implemented yet)
/// CodeGenerator trait serves as an interface to the backend code
/// generator, which may generate assembly code or binary (not implemented
/// yet)
use compiler::backend::x86_64::codegen::CodeGenerator;
/// assembly backend as AOT compiler
......@@ -54,16 +55,22 @@ use utils::LinkedHashMap;
// number of normal callee saved registers (excluding RSP and RBP)
pub const CALLEE_SAVED_COUNT: usize = 5;
/// a macro to declare a set of general purpose registers that are aliased to the first one
/// a macro to declare a set of general purpose registers that are aliased to
/// the first one
macro_rules! GPR_ALIAS {
($alias: ident: ($id64: expr, $r64: ident) ->
$r32: ident, $r16: ident, $r8l: ident, $r8h: ident) => {
lazy_static! {
pub static ref $r64: P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32: P<Value> = GPR!($id64 + 1, stringify!($r32), UINT32_TYPE);
pub static ref $r16: P<Value> = GPR!($id64 + 2, stringify!($r16), UINT16_TYPE);
pub static ref $r8l: P<Value> = GPR!($id64 + 3, stringify!($r8l), UINT8_TYPE);
pub static ref $r8h: P<Value> = GPR!($id64 + 4, stringify!($r8h), UINT8_TYPE);
pub static ref $r64: P<Value> =
GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32: P<Value> =
GPR!($id64 + 1, stringify!($r32), UINT32_TYPE);
pub static ref $r16: P<Value> =
GPR!($id64 + 2, stringify!($r16), UINT16_TYPE);
pub static ref $r8l: P<Value> =
GPR!($id64 + 3, stringify!($r8l), UINT8_TYPE);
pub static ref $r8h: P<Value> =
GPR!($id64 + 4, stringify!($r8h), UINT8_TYPE);
pub static ref $alias: [P<Value>; 5] = [
$r64.clone(),
$r32.clone(),
......@@ -76,10 +83,14 @@ macro_rules! GPR_ALIAS {
($alias: ident: ($id64: expr, $r64: ident) -> $r32: ident, $r16: ident, $r8: ident) => {
lazy_static! {
pub static ref $r64: P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32: P<Value> = GPR!($id64 + 1, stringify!($r32), UINT32_TYPE);
pub static ref $r16: P<Value> = GPR!($id64 + 2, stringify!($r16), UINT16_TYPE);
pub static ref $r8: P<Value> = GPR!($id64 + 3, stringify!($r8), UINT8_TYPE);
pub static ref $r64: P<Value> =
GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32: P<Value> =
GPR!($id64 + 1, stringify!($r32), UINT32_TYPE);
pub static ref $r16: P<Value> =
GPR!($id64 + 2, stringify!($r16), UINT16_TYPE);
pub static ref $r8: P<Value> =
GPR!($id64 + 3, stringify!($r8), UINT8_TYPE);
pub static ref $alias: [P<Value>; 4] =
[$r64.clone(), $r32.clone(), $r16.clone(), $r8.clone()];
}
......@@ -87,7 +98,8 @@ macro_rules! GPR_ALIAS {
($alias: ident: ($id64: expr, $r64: ident)) => {
lazy_static! {
pub static ref $r64: P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r64: P<Value> =
GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $alias: [P<Value>; 4] =
[$r64.clone(), $r64.clone(), $r64.clone(), $r64.clone()];
}
......@@ -100,7 +112,7 @@ macro_rules! GPR {
P(Value {
hdr: MuEntityHeader::named($id, Arc::new($name.to_string())),
ty: $ty.clone(),
v: Value_::SSAVar($id),
v: Value_::SSAVar($id)
})
}};
}
......@@ -111,7 +123,7 @@ macro_rules! FPR {
P(Value {
hdr: MuEntityHeader::named($id, Arc::new($name.to_string())),
ty: DOUBLE_TYPE.clone(),
v: Value_::SSAVar($id),
v: Value_::SSAVar($id)
})
}};
}
......@@ -186,7 +198,7 @@ pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
if id < FPR_ID_START {
let vec = match GPR_ALIAS_TABLE.get(&id) {
Some(vec) => vec,
None => panic!("didnt find {} as GPR", id),
None => panic!("didnt find {} as GPR", id)
};
match length {
......@@ -195,7 +207,7 @@ pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
16 => vec[2].clone(),
8 => vec[3].clone(),
1 => vec[3].clone(),
_ => panic!("unexpected length {} for {}", length, vec[0]),
_ => panic!("unexpected length {} for {}", length, vec[0])
}
} else {
for r in ALL_FPRS.iter() {
......@@ -208,11 +220,13 @@ pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
}
}
/// are two registers aliased? (both must be machine register IDs, otherwise this function panics)
/// are two registers aliased? (both must be machine register IDs, otherwise
/// this function panics)
pub fn is_aliased(id1: MuID, id2: MuID) -> bool {
if get_color_for_precolored(id1) == get_color_for_precolored(id2) {
// we need to specially check the case for AH/BH/CH/DH
// because both AH and AL are aliased to RAX, but AH and AL are not aliased
// because both AH and AL are aliased to RAX, but AH and AL are not
// aliased
macro_rules! is_match {
($a1: expr, $a2: expr; $b: expr) => {
$a1 == $b.id() || $a2 == $b.id()
......@@ -242,7 +256,7 @@ pub fn get_color_for_precolored(id: MuID) -> MuID {
if id < FPR_ID_START {
match GPR_ALIAS_LOOKUP.get(&id) {
Some(val) => val.id(),
None => panic!("cannot find GPR {}", id),
None => panic!("cannot find GPR {}", id)
}
} else {
// we do not have alias for FPRs
......@@ -259,7 +273,7 @@ pub fn check_op_len(op: &P<Value>) -> usize {
Some(16) => 16,
Some(8) => 8,
Some(1) => 8,
_ => panic!("unsupported register length for x64: {}", op.ty),
_ => panic!("unsupported register length for x64: {}", op.ty)
}
}
......@@ -529,7 +543,7 @@ pub fn number_of_usable_regs_in_group(group: RegGroup) -> usize {
match group {
RegGroup::GPR => ALL_USABLE_GPRS.len(),
RegGroup::GPREX => ALL_USABLE_GPRS.len(),
RegGroup::FPR => ALL_USABLE_FPRS.len(),
RegGroup::FPR => ALL_USABLE_FPRS.len()
}
}
......@@ -569,7 +583,10 @@ pub fn get_return_address(frame_pointer: Address) -> Address {
/// gets the stack pointer before the current frame was created