WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit c3ba71ac authored by John Zhang's avatar John Zhang
Browse files

Merge branch 'master' into ci-script

parents 00c57362 a241c754
**/target/* **/target/*
**/__pycache__/* **/__pycache__/*
**/.cache/*
emit/* emit/*
**/temp/* **/temp/*
Cargo.lock Cargo.lock
......
...@@ -35,21 +35,21 @@ test:cargo:api: ...@@ -35,21 +35,21 @@ test:cargo:api:
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 CC=clang cargo test test_api - RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_api
test:cargo:ir: test:cargo:ir:
stage: test stage: test
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 CC=clang cargo test test_ir - RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_ir
test:cargo:compiler: test:cargo:compiler:
stage: test stage: test
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 CC=clang cargo test test_compiler - RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_compiler
test:cargo:runtime: test:cargo:runtime:
stage: test stage: test
...@@ -63,6 +63,7 @@ testjit:milestones: ...@@ -63,6 +63,7 @@ testjit:milestones:
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_milestones.py - RUST_BACKTRACE=1 pytest tests/test_jit/test_milestones.py
testjit:binops: testjit:binops:
...@@ -70,6 +71,7 @@ testjit:binops: ...@@ -70,6 +71,7 @@ testjit:binops:
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_binops.py - RUST_BACKTRACE=1 pytest tests/test_jit/test_binops.py
testjit:cmpops: testjit:cmpops:
...@@ -77,4 +79,11 @@ testjit:cmpops: ...@@ -77,4 +79,11 @@ testjit:cmpops:
dependencies: dependencies:
- build_test - build_test
script: script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_cmpops.py - RUST_BACKTRACE=1 pytest tests/test_jit/test_cmpops.py
testjit:cmpops:
stage: test
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_convops.py
\ No newline at end of file
...@@ -64,6 +64,8 @@ echo "KERNEL: $KERNEL" ...@@ -64,6 +64,8 @@ echo "KERNEL: $KERNEL"
echo "ARCH: $MACH" echo "ARCH: $MACH"
echo "---------" echo "---------"
rm emit/*
if [ "$OS" == "linux" ]; then if [ "$OS" == "linux" ]; then
RUSTFLAGS=-Zincremental=target/incr-cache RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang-3.8 cargo test "$@" RUSTFLAGS=-Zincremental=target/incr-cache RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang-3.8 cargo test "$@"
elif [ "$OS" == "Darwin" ]; then elif [ "$OS" == "Darwin" ]; then
......
...@@ -91,6 +91,12 @@ pub enum Instruction_ { ...@@ -91,6 +91,12 @@ pub enum Instruction_ {
BinOp(BinOp, OpIndex, OpIndex), BinOp(BinOp, OpIndex, OpIndex),
CmpOp(CmpOp, OpIndex, OpIndex), CmpOp(CmpOp, OpIndex, OpIndex),
ConvOp{
operation: ConvOp,
from_ty: P<MuType>,
to_ty: P<MuType>,
operand: OpIndex
},
// yields a tuple of results from the call // yields a tuple of results from the call
ExprCall{ ExprCall{
...@@ -254,6 +260,9 @@ impl Instruction_ { ...@@ -254,6 +260,9 @@ impl Instruction_ {
match self { match self {
&Instruction_::BinOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]), &Instruction_::BinOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]),
&Instruction_::CmpOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]), &Instruction_::CmpOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]),
&Instruction_::ConvOp{operation, ref from_ty, ref to_ty, operand} => {
format!("{:?} {} {} {}", operation, from_ty, to_ty, ops[operand])
}
&Instruction_::ExprCall{ref data, is_abort} => { &Instruction_::ExprCall{ref data, is_abort} => {
let abort = select_value!(is_abort, "ABORT_ON_EXN", "RETHROW"); let abort = select_value!(is_abort, "ABORT_ON_EXN", "RETHROW");
format!("CALL {} {}", data.debug_str(ops), abort) format!("CALL {} {}", data.debug_str(ops), abort)
......
...@@ -4,6 +4,7 @@ use inst::*; ...@@ -4,6 +4,7 @@ use inst::*;
use op::*; use op::*;
use utils::vec_utils; use utils::vec_utils;
use utils::Address;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
...@@ -735,6 +736,8 @@ pub enum Constant { ...@@ -735,6 +736,8 @@ pub enum Constant {
FuncRef(MuID), FuncRef(MuID),
UFuncRef(MuID), UFuncRef(MuID),
Vector(Vec<Constant>), Vector(Vec<Constant>),
//Pointer(Address),
NullRef,
} }
impl fmt::Display for Constant { impl fmt::Display for Constant {
...@@ -756,6 +759,7 @@ impl fmt::Display for Constant { ...@@ -756,6 +759,7 @@ impl fmt::Display for Constant {
} }
write!(f, "]") write!(f, "]")
} }
&Constant::NullRef => write!(f, "NullRef"),
} }
} }
} }
......
...@@ -5,6 +5,7 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool { ...@@ -5,6 +5,7 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
match inst { match inst {
&BinOp(_, _, _) &BinOp(_, _, _)
| &CmpOp(_, _, _) | &CmpOp(_, _, _)
| &ConvOp{..}
| &ExprCall{..} | &ExprCall{..}
| &Load{..} | &Load{..}
| &Store{..} | &Store{..}
...@@ -49,6 +50,7 @@ pub fn has_side_effect(inst: &Instruction_) -> bool { ...@@ -49,6 +50,7 @@ pub fn has_side_effect(inst: &Instruction_) -> bool {
match inst { match inst {
&BinOp(_, _, _) => false, &BinOp(_, _, _) => false,
&CmpOp(_, _, _) => false, &CmpOp(_, _, _) => false,
&ConvOp{..} => false,
&ExprCall{..} => true, &ExprCall{..} => true,
&Load{..} => true, &Load{..} => true,
&Store{..} => true, &Store{..} => true,
......
...@@ -35,6 +35,7 @@ pub enum OpCode { ...@@ -35,6 +35,7 @@ pub enum OpCode {
// expression // expression
Binary(BinOp), Binary(BinOp),
Comparison(CmpOp), Comparison(CmpOp),
Conversion(ConvOp),
AtomicRMW(AtomicRMWOp), AtomicRMW(AtomicRMWOp),
ExprCall, ExprCall,
...@@ -172,6 +173,22 @@ pub enum CmpOp { ...@@ -172,6 +173,22 @@ pub enum CmpOp {
FUNO FUNO
} }
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum ConvOp {
TRUNC,
ZEXT,
SEXT,
FPTRUNC,
FPEXT,
FPTOUI,
FPTOSI,
UITOFP,
SITOFP,
BITCAST,
REFCAST,
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum AtomicRMWOp { pub enum AtomicRMWOp {
XCHG, XCHG,
...@@ -207,6 +224,7 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode { ...@@ -207,6 +224,7 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
match inst.v { match inst.v {
Instruction_::BinOp(op, _, _) => OpCode::Binary(op), Instruction_::BinOp(op, _, _) => OpCode::Binary(op),
Instruction_::CmpOp(op, _, _) => OpCode::Comparison(op), Instruction_::CmpOp(op, _, _) => OpCode::Comparison(op),
Instruction_::ConvOp{operation, ..} => OpCode::Conversion(operation),
Instruction_::AtomicRMW{op, ..} => OpCode::AtomicRMW(op), Instruction_::AtomicRMW{op, ..} => OpCode::AtomicRMW(op),
Instruction_::ExprCall{..} => OpCode::ExprCall, Instruction_::ExprCall{..} => OpCode::ExprCall,
Instruction_::Load{..} => OpCode::Load, Instruction_::Load{..} => OpCode::Load,
......
...@@ -13,6 +13,14 @@ lazy_static! { ...@@ -13,6 +13,14 @@ lazy_static! {
MuType::new(new_internal_id(), MuType_::int(POINTER_SIZE * 8)) MuType::new(new_internal_id(), MuType_::int(POINTER_SIZE * 8))
); );
pub static ref UINT8_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(8))
);
pub static ref UINT16_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(16))
);
pub static ref UINT32_TYPE : P<MuType> = P( pub static ref UINT32_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(32)) MuType::new(new_internal_id(), MuType_::int(32))
); );
...@@ -27,6 +35,8 @@ lazy_static! { ...@@ -27,6 +35,8 @@ lazy_static! {
pub static ref INTERNAL_TYPES : Vec<P<MuType>> = vec![ pub static ref INTERNAL_TYPES : Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(), ADDRESS_TYPE.clone(),
UINT8_TYPE.clone(),
UINT16_TYPE.clone(),
UINT32_TYPE.clone(), UINT32_TYPE.clone(),
UINT64_TYPE.clone(), UINT64_TYPE.clone(),
DOUBLE_TYPE.clone() DOUBLE_TYPE.clone()
......
...@@ -4,6 +4,9 @@ use runtime::ValueLocation; ...@@ -4,6 +4,9 @@ use runtime::ValueLocation;
use compiler::machine_code::MachineCode; use compiler::machine_code::MachineCode;
pub type Reg<'a> = &'a P<Value>;
pub type Mem<'a> = &'a P<Value>;
pub trait CodeGenerator { pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation; fn start_code(&mut self, func_name: MuName) -> ValueLocation;
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);
...@@ -22,47 +25,187 @@ pub trait CodeGenerator { ...@@ -22,47 +25,187 @@ pub trait CodeGenerator {
fn emit_nop(&mut self, bytes: usize); fn emit_nop(&mut self, bytes: usize);
fn emit_cmp_r64_r64(&mut self, op1: &P<Value>, op2: &P<Value>); // comparison
fn emit_cmp_r64_imm32(&mut self, op1: &P<Value>, op2: i32); fn emit_cmp_r64_r64 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r64_mem64(&mut self, op1: &P<Value>, op2: &P<Value>); fn emit_cmp_r64_imm32(&mut self, op1: Reg, op2: i32);
fn emit_cmp_r64_mem64(&mut self, op1: Reg, op2: Mem);
fn emit_mov_r64_imm32 (&mut self, dest: &P<Value>, src: i32);
fn emit_mov_r64_mem64 (&mut self, dest: &P<Value>, src: &P<Value>); // load fn emit_cmp_r32_r32 (&mut self, op1: Reg, op2: Reg);
fn emit_mov_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); fn emit_cmp_r32_imm32(&mut self, op1: Reg, op2: i32);
fn emit_mov_mem64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); // store fn emit_cmp_r32_mem32(&mut self, op1: Reg, op2: Mem);
fn emit_mov_mem64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_cmp_r16_r16 (&mut self, op1: Reg, op2: Reg);
fn emit_movsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>); fn emit_cmp_r16_imm16(&mut self, op1: Reg, op2: i16);
fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); // load fn emit_cmp_r16_mem16(&mut self, op1: Reg, op2: Mem);
fn emit_movsd_mem64_f64(&mut self, dest: &P<Value>, src: &P<Value>); // store
fn emit_cmp_r8_r8 (&mut self, op1: Reg, op2: Reg);
fn emit_lea_r64(&mut self, dest: &P<Value>, src: &P<Value>); fn emit_cmp_r8_imm8 (&mut self, op1: Reg, op2: i8);
fn emit_cmp_r8_mem8 (&mut self, op1: Reg, op2: Mem);
fn emit_and_r64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_and_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); // gpr move
fn emit_xor_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_r64_imm32 (&mut self, dest: Reg, src: i32);
fn emit_xor_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_r64_mem64 (&mut self, dest: Reg, src: Mem); // load
fn emit_xor_r64_imm32(&mut self, dest: &P<Value>, src: i32); fn emit_mov_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem64_r64 (&mut self, dest: Mem, src: Reg); // store
fn emit_add_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_mem64_imm32(&mut self, dest: Mem, src: i32);
fn emit_add_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_add_r64_imm32(&mut self, dest: &P<Value>, src: i32); fn emit_mov_r32_imm32 (&mut self, dest: Reg, src: i32);
fn emit_mov_r32_mem32 (&mut self, dest: Reg, src: Mem); // load
fn emit_addsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_addsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_mem32_r32 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem32_imm32(&mut self, dest: Mem, src: i32);
fn emit_sub_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_sub_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); fn emit_mov_r16_imm16 (&mut self, dest: Reg, src: i16);
fn emit_sub_r64_imm32(&mut self, dest: &P<Value>, src: i32); fn emit_mov_r16_mem16 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_mul_r64 (&mut self, src: &P<Value>); fn emit_mov_mem16_r16 (&mut self, dest: Mem, src: Reg); // store
fn emit_mul_mem64(&mut self, src: &P<Value>); fn emit_mov_mem16_imm16(&mut self, dest: Mem, src: i16);
fn emit_div_r64 (&mut self, src: &P<Value>); fn emit_mov_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_div_mem64 (&mut self, src: &P<Value>); fn emit_mov_r8_mem8 (&mut self, dest: Reg, src: Mem); // load
fn emit_idiv_r64 (&mut self, src: &P<Value>); fn emit_mov_r8_r8 (&mut self, dest: Reg, src: Mem);
fn emit_idiv_mem64(&mut self, src: &P<Value>); fn emit_mov_mem8_r8 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem8_imm8 (&mut self, dest: Mem, src: i8);
// lea
fn emit_lea_r64(&mut self, dest: Reg, src: Reg);
// and
fn emit_and_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_and_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_and_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_and_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_and_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_and_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_and_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_and_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_and_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_and_r8_mem8 (&mut self, dest: Reg, src: Mem);
// xor
fn emit_xor_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_xor_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_xor_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_xor_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_xor_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_mem16(&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_xor_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_mem8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_imm8 (&mut self, dest: Reg, src: i8);
// add
fn emit_add_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_add_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_add_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_add_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_add_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_add_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_add_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_add_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_add_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_add_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_add_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_add_r8_imm8(&mut self, dest: Reg, src: i8);
// sub
fn emit_sub_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_sub_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_sub_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_sub_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_sub_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_sub_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_sub_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_sub_r8_imm8(&mut self, dest: Reg, src: i8);
// floating point
fn emit_addsd_f64_f64 (&mut self, dest: Reg, src: Reg);
fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);
// multiply
fn emit_mul_r64 (&mut self, src: Reg);
fn emit_mul_r32 (&mut self, src: Reg);
fn emit_mul_r16 (&mut self, src: Reg);
fn emit_mul_r8 (&mut self, src: Reg);
fn emit_mul_mem64(&mut self, src: Mem);
fn emit_mul_mem32(&mut self, src: Mem);
fn emit_mul_mem16(&mut self, src: Mem);
fn emit_mul_mem8 (&mut self, src: Mem);
// div
fn emit_div_r64 (&mut self, src: Reg);
fn emit_div_r32 (&mut self, src: Reg);
fn emit_div_r16 (&mut self, src: Reg);
fn emit_div_r8 (&mut self, src: Reg);
fn emit_div_mem64 (&mut self, src: Mem);
fn emit_div_mem32 (&mut self, src: Mem);
fn emit_div_mem16 (&mut self, src: Mem);
fn emit_div_mem8 (&mut self, src: Mem);
// idiv
fn emit_idiv_r64 (&mut self, src: Reg);
fn emit_idiv_r32 (&mut self, src: Reg);
fn emit_idiv_r16 (&mut self, src: Reg);
fn emit_idiv_r8 (&mut self, src: Reg);
fn emit_idiv_mem64(&mut self, src: Mem);
fn emit_idiv_mem32(&mut self, src: Mem);
fn emit_idiv_mem16(&mut self, src: Mem);
fn emit_idiv_mem8 (&mut self, src: Mem);
// shl
fn emit_shl_r64_cl (&mut self, dest: Reg);
// fn emit_shl_r32_cl (&mut self, dest: Reg);
// fn emit_shl_r16_cl (&mut self, dest: Reg);
// fn emit_shl_r8_cl (&mut self, dest: Reg);
fn emit_shl_mem64_cl (&mut self, dest: Mem);
// fn emit_shl_mem32_cl (&mut self, dest: Mem);
// fn emit_shl_mem16_cl (&mut self, dest: Mem);
// fn emit_shl_mem8_cl (&mut self, dest: Mem);
fn emit_shl_r64_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r32_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r16_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_shl_mem64_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem32_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem16_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem8_imm8 (&mut self, dest: Mem, src: i8);
fn emit_shr_r64_cl (&mut self, dest: &P<Value>);
fn emit_shr_mem64_cl (&mut self, dest: &P<Value>);
fn emit_shr_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_shr_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_sar_r64_cl (&mut self, dest: &P<Value>);
fn emit_sar_mem64_cl (&mut self, dest: &P<Value>);
fn emit_sar_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_sar_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_cqo(&mut self); fn emit_cqo(&mut self);
...@@ -87,4 +230,10 @@ pub trait CodeGenerator { ...@@ -87,4 +230,10 @@ pub trait CodeGenerator {
fn emit_push_r64(&mut self, src: &P<Value>); fn emit_push_r64(&mut self, src: &P<Value>);
fn emit_push_imm32(&mut self, src: i32); fn emit_push_imm32(&mut self, src: i32);
fn emit_pop_r64(&mut self, dest: &P<Value>); fn emit_pop_r64(&mut self, dest: &P<Value>);
// fpr move
fn emit_movsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); // load
fn emit_movsd_mem64_f64(&mut self, dest: &P<Value>, src: &P<Value>); // store
} }
\ No newline at end of file
...@@ -171,3 +171,30 @@ pub struct BackendTypeInfo { ...@@ -171,3 +171,30 @@ pub struct BackendTypeInfo {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum RegGroup {GPR, FPR} pub enum RegGroup {GPR, FPR}
impl RegGroup {
pub fn get(ty: &P<MuType>) -> RegGroup {
match ty.v {
// for now, only use 64bits registers
MuType_::Int(len) if len == 8 => RegGroup::GPR,
MuType_::Int(len) if len == 16 => RegGroup::GPR,
MuType_::Int(len) if len == 32 => RegGroup::GPR,
MuType_::Int(len) if len == 64 => RegGroup::GPR,
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_)
| MuType_::UPtr(_)
| MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64
| MuType_::FuncRef(_)
| MuType_::UFuncPtr(_) => RegGroup::GPR,
MuType_::Float => RegGroup::FPR,
MuType_::Double => RegGroup::FPR,
_ => unimplemented!()
}
}
}
\ No newline at end of file