Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-fast
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
40
Issues
40
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
mu
mu-impl-fast
Commits
04c10e0b
Commit
04c10e0b
authored
Jul 29, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed all tests. Now using a lock for MuName
parent
b20cc1a4
Changes
21
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
334 additions
and
299 deletions
+334
-299
src/ast/ir.rs
src/ast/ir.rs
+78
-61
src/ast/ptr.rs
src/ast/ptr.rs
+69
-67
src/ast/types.rs
src/ast/types.rs
+7
-10
src/compiler/backend/arch/x86_64/asm_backend.rs
src/compiler/backend/arch/x86_64/asm_backend.rs
+27
-18
src/compiler/backend/arch/x86_64/inst_sel.rs
src/compiler/backend/arch/x86_64/inst_sel.rs
+7
-9
src/compiler/backend/arch/x86_64/mod.rs
src/compiler/backend/arch/x86_64/mod.rs
+53
-47
src/compiler/backend/mod.rs
src/compiler/backend/mod.rs
+4
-3
src/compiler/backend/peephole_opt.rs
src/compiler/backend/peephole_opt.rs
+1
-1
src/compiler/backend/reg_alloc/graph_coloring/coloring.rs
src/compiler/backend/reg_alloc/graph_coloring/coloring.rs
+1
-1
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
+2
-2
src/compiler/backend/reg_alloc/mod.rs
src/compiler/backend/reg_alloc/mod.rs
+1
-1
src/compiler/passes/def_use.rs
src/compiler/passes/def_use.rs
+1
-1
src/compiler/passes/mod.rs
src/compiler/passes/mod.rs
+1
-1
src/vm/context.rs
src/vm/context.rs
+18
-18
tests/test_compiler/mod.rs
tests/test_compiler/mod.rs
+1
-1
tests/test_compiler/test_global.rs
tests/test_compiler/test_global.rs
+5
-3
tests/test_compiler/test_instsel.rs
tests/test_compiler/test_instsel.rs
+2
-1
tests/test_compiler/test_pre_instsel.rs
tests/test_compiler/test_pre_instsel.rs
+6
-6
tests/test_compiler/test_regalloc.rs
tests/test_compiler/test_regalloc.rs
+3
-3
tests/test_ir/test_ir.rs
tests/test_ir/test_ir.rs
+45
-44
tests/test_ir/test_types.rs
tests/test_ir/test_types.rs
+2
-1
No files found.
src/ast/ir.rs
View file @
04c10e0b
...
...
@@ -8,6 +8,7 @@ use utils::vec_utils;
use
std
::
collections
::
HashMap
;
use
std
::
fmt
;
use
std
::
default
;
use
std
::
sync
::
RwLock
;
use
std
::
cell
::
Cell
;
use
std
::
sync
::
atomic
::{
AtomicUsize
,
ATOMIC_USIZE_INIT
,
Ordering
};
...
...
@@ -55,8 +56,7 @@ pub fn new_internal_id() -> MuID {
#[derive(Debug)]
pub
struct
MuFunction
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
sig
:
P
<
MuFuncSig
>
,
pub
cur_ver
:
Option
<
MuID
>
,
...
...
@@ -66,8 +66,7 @@ pub struct MuFunction {
impl
MuFunction
{
pub
fn
new
(
id
:
MuID
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunction
{
MuFunction
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
sig
:
sig
,
cur_ver
:
None
,
all_vers
:
vec!
[]
...
...
@@ -77,18 +76,13 @@ impl MuFunction {
impl
fmt
::
Display
for
MuFunction
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
if
self
.name
.is_none
()
{
write!
(
f
,
"Func #{}"
,
self
.id
)
}
else
{
write!
(
f
,
"Func {}#{}"
,
self
.name
.unwrap
(),
self
.id
)
}
write!
(
f
,
"Func {}"
,
self
.hdr
)
}
}
#[derive(Debug)]
pub
struct
MuFunctionVersion
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
func_id
:
MuID
,
pub
sig
:
P
<
MuFuncSig
>
,
...
...
@@ -100,19 +94,14 @@ pub struct MuFunctionVersion {
impl
fmt
::
Display
for
MuFunctionVersion
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
if
self
.name
.is_none
()
{
write!
(
f
,
"FuncVer #{} of Func#{}"
,
self
.id
,
self
.func_id
)
}
else
{
write!
(
f
,
"FuncVer {}#{} of Func#{}"
,
self
.name
.unwrap
(),
self
.id
,
self
.func_id
)
}
write!
(
f
,
"FuncVer {} of Func #{}"
,
self
.hdr
,
self
.func_id
)
}
}
impl
MuFunctionVersion
{
pub
fn
new
(
id
:
MuID
,
func
:
MuID
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunctionVersion
{
MuFunctionVersion
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
func_id
:
func
,
sig
:
sig
,
content
:
None
,
...
...
@@ -129,12 +118,10 @@ impl MuFunctionVersion {
self
.context.values
.insert
(
id
,
SSAVarEntry
{
id
:
id
,
name
:
Some
(
tag
),
ty
:
ty
.clone
(),
use_count
:
Cell
::
new
(
0
),
expr
:
None
});
P
(
TreeNode
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_ssa
(
&
ty
),
v
:
TreeNode_
::
Value
(
P
(
Value
{
id
:
id
,
name
:
Some
(
tag
),
hdr
:
MuEntityHeader
::
named
(
id
,
tag
),
ty
:
ty
,
v
:
Value_
::
SSAVar
(
id
)
}))
...
...
@@ -143,8 +130,7 @@ impl MuFunctionVersion {
pub
fn
new_constant
(
&
mut
self
,
id
:
MuID
,
v
:
P
<
Value
>
)
->
P
<
TreeNode
>
{
P
(
TreeNode
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_value
(
&
v
.ty
),
v
:
TreeNode_
::
Value
(
v
)
})
...
...
@@ -152,8 +138,7 @@ impl MuFunctionVersion {
pub
fn
new_global
(
&
mut
self
,
id
:
MuID
,
v
:
P
<
Value
>
)
->
P
<
TreeNode
>
{
P
(
TreeNode
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_value
(
&
v
.ty
),
v
:
TreeNode_
::
Value
(
v
)
})
...
...
@@ -161,8 +146,7 @@ impl MuFunctionVersion {
pub
fn
new_inst
(
&
mut
self
,
id
:
MuID
,
v
:
Instruction
)
->
P
<
TreeNode
>
{
P
(
TreeNode
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_inst
(
&
v
),
v
:
TreeNode_
::
Instruction
(
v
),
})
...
...
@@ -243,15 +227,14 @@ impl FunctionContext {
#[derive(Debug)]
pub
struct
Block
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
content
:
Option
<
BlockContent
>
,
pub
control_flow
:
ControlFlow
}
impl
Block
{
pub
fn
new
(
id
:
MuID
)
->
Block
{
Block
{
id
:
id
,
name
:
None
,
content
:
None
,
control_flow
:
ControlFlow
::
default
()}
Block
{
hdr
:
MuEntityHeader
::
unnamed
(
id
)
,
content
:
None
,
control_flow
:
ControlFlow
::
default
()}
}
}
...
...
@@ -391,11 +374,10 @@ impl BlockContent {
}
}
#[derive(Debug
,
Clone
)]
#[derive(Debug)]
/// always use with P<TreeNode>
pub
struct
TreeNode
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
op
:
OpCode
,
pub
v
:
TreeNode_
,
}
...
...
@@ -404,8 +386,7 @@ impl TreeNode {
// this is a hack to allow creating TreeNode without using a &mut MuFunctionVersion
pub
fn
new_inst
(
id
:
MuID
,
v
:
Instruction
)
->
P
<
TreeNode
>
{
P
(
TreeNode
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_inst
(
&
v
),
v
:
TreeNode_
::
Instruction
(
v
),
})
...
...
@@ -464,10 +445,9 @@ pub enum TreeNode_ {
}
/// always use with P<Value>
#[derive(Debug,
Clone,
PartialEq)]
#[derive(Debug,
PartialEq)]
pub
struct
Value
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
ty
:
P
<
MuType
>
,
pub
v
:
Value_
}
...
...
@@ -522,25 +502,18 @@ impl Value {
impl
fmt
::
Display
for
Value
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
let
tag
=
{
if
self
.name
.is_some
()
{
self
.name
.unwrap
()
}
else
{
"???"
}
};
match
self
.v
{
Value_
::
SSAVar
(
id
)
=>
{
write!
(
f
,
"+({} %{}
#{})"
,
self
.ty
,
tag
,
id
)
write!
(
f
,
"+({} %{}
)"
,
self
.ty
,
self
.hdr
)
},
Value_
::
Constant
(
ref
c
)
=>
{
write!
(
f
,
"+({} {}
)"
,
self
.ty
,
c
)
write!
(
f
,
"+({} {}
@{})"
,
self
.ty
,
c
,
self
.hdr
)
},
Value_
::
Global
=>
{
write!
(
f
,
"+(GLOBAL {} @{})"
,
self
.ty
,
self
.name
.unwrap
()
)
Value_
::
Global
(
ref
ty
)
=>
{
write!
(
f
,
"+(GLOBAL {} @{})"
,
ty
,
self
.hdr
)
},
Value_
::
Memory
(
ref
mem
)
=>
{
write!
(
f
,
"+(
{})"
,
mem
)
write!
(
f
,
"+(
MEM {} %{})"
,
mem
,
self
.hdr
)
}
}
}
...
...
@@ -550,7 +523,7 @@ impl fmt::Display for Value {
pub
enum
Value_
{
SSAVar
(
MuID
),
Constant
(
Constant
),
Global
,
Global
(
P
<
MuType
>
),
// what type is this global (without IRef)
Memory
(
MemoryLocation
)
}
...
...
@@ -649,30 +622,74 @@ impl fmt::Display for MemoryLocation {
}
}
#[derive(Debug)]
// Display, PartialEq
pub
struct
MuEntityHeader
{
id
:
MuID
,
name
:
RwLock
<
Option
<
MuName
>>
}
impl
MuEntityHeader
{
pub
fn
unnamed
(
id
:
MuID
)
->
MuEntityHeader
{
MuEntityHeader
{
id
:
id
,
name
:
RwLock
::
new
(
None
)
}
}
pub
fn
named
(
id
:
MuID
,
name
:
MuName
)
->
MuEntityHeader
{
MuEntityHeader
{
id
:
id
,
name
:
RwLock
::
new
(
Some
(
name
))
}
}
pub
fn
id
(
&
self
)
->
MuID
{
self
.id
}
pub
fn
name
(
&
self
)
->
Option
<
MuName
>
{
*
self
.name
.read
()
.unwrap
()
}
}
impl
PartialEq
for
MuEntityHeader
{
fn
eq
(
&
self
,
other
:
&
Self
)
->
bool
{
self
.id
==
other
.id
}
}
impl
fmt
::
Display
for
MuEntityHeader
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
if
self
.name
()
.is_none
()
{
write!
(
f
,
"#{}"
,
self
.id
)
}
else
{
write!
(
f
,
"{} #{}"
,
self
.name
()
.unwrap
(),
self
.id
)
}
}
}
pub
trait
MuEntity
{
fn
id
(
&
self
)
->
MuID
;
fn
name
(
&
self
)
->
Option
<
MuName
>
;
fn
set_name
(
&
mut
self
,
name
:
MuName
);
fn
set_name
(
&
self
,
name
:
MuName
);
fn
as_entity
(
&
self
)
->
&
MuEntity
;
fn
as_entity_mut
(
&
mut
self
)
->
&
mut
MuEntity
;
}
macro_rules!
impl_mu_entity
{
(
$entity
:
ty
)
=>
{
impl
MuEntity
for
$entity
{
#[inline(always)]
fn
id
(
&
self
)
->
MuID
{
self
.id
}
fn
id
(
&
self
)
->
MuID
{
self
.
hdr.
id
}
#[inline(always)]
fn
name
(
&
self
)
->
Option
<
MuName
>
{
self
.name
}
fn
set_name
(
&
mut
self
,
name
:
MuName
)
{
self
.name
=
Some
(
name
);}
fn
name
(
&
self
)
->
Option
<
MuName
>
{
self
.hdr
.name
()}
fn
set_name
(
&
self
,
name
:
MuName
)
{
let
mut
write_guard
=
self
.hdr.name
.write
()
.unwrap
();
*
write_guard
=
Some
(
name
);
}
fn
as_entity
(
&
self
)
->
&
MuEntity
{
let
ref_ty
:
&
$entity
=
self
;
ref_ty
as
&
MuEntity
}
fn
as_entity_mut
(
&
mut
self
)
->
&
mut
MuEntity
{
let
ref_ty
:
&
mut
$entity
=
self
;
ref_ty
as
&
mut
MuEntity
}
}
}
}
...
...
src/ast/ptr.rs
View file @
04c10e0b
...
...
@@ -41,76 +41,78 @@ use std::hash::{Hash, Hasher};
use
std
::
ops
::
Deref
;
use
std
::
ops
::
DerefMut
;
/// An owned smart pointer.
pub
struct
P
<
T
>
{
ptr
:
Box
<
T
>
}
use
std
::
sync
::
Arc
;
pub
type
P
<
T
>
=
Arc
<
T
>
;
///// An owned smart pointer.
//pub struct P<T> {
// ptr: Box<T>
//}
#[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value.
pub
fn
P
<
T
:
'static
>
(
value
:
T
)
->
P
<
T
>
{
P
{
ptr
:
Box
::
new
(
value
)
}
}
impl
<
T
:
'static
>
P
<
T
>
{
/// Move out of the pointer.
/// Intended for chaining transformations not covered by `map`.
pub
fn
and_then
<
U
,
F
>
(
self
,
f
:
F
)
->
U
where
F
:
FnOnce
(
T
)
->
U
,
{
f
(
*
self
.ptr
)
}
}
impl
<
T
>
Deref
for
P
<
T
>
{
type
Target
=
T
;
fn
deref
<
'a
>
(
&
'a
self
)
->
&
'a
T
{
&*
self
.ptr
}
}
impl
<
T
>
DerefMut
for
P
<
T
>
{
fn
deref_mut
<
'a
>
(
&
'a
mut
self
)
->
&
'a
mut
T
{
&
mut
*
self
.ptr
}
}
impl
<
T
:
'static
+
Clone
>
Clone
for
P
<
T
>
{
fn
clone
(
&
self
)
->
P
<
T
>
{
P
((
**
self
)
.clone
())
}
}
impl
<
T
:
PartialEq
>
PartialEq
for
P
<
T
>
{
fn
eq
(
&
self
,
other
:
&
P
<
T
>
)
->
bool
{
**
self
==
**
other
}
}
impl
<
T
:
Eq
>
Eq
for
P
<
T
>
{}
impl
<
T
:
Debug
>
Debug
for
P
<
T
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
Debug
::
fmt
(
&**
self
,
f
)
}
}
impl
<
T
:
Display
>
Display
for
P
<
T
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
Display
::
fmt
(
&**
self
,
f
)
}
}
impl
<
T
>
fmt
::
Pointer
for
P
<
T
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
fmt
::
Pointer
::
fmt
(
&
self
.ptr
,
f
)
}
Arc
::
new
(
value
)
}
impl
<
T
:
Hash
>
Hash
for
P
<
T
>
{
fn
hash
<
H
:
Hasher
>
(
&
self
,
state
:
&
mut
H
)
{
(
**
self
)
.hash
(
state
);
}
}
//impl<T: 'static> P<T> {
// /// Move out of the pointer.
// /// Intended for chaining transformations not covered by `map`.
// pub fn and_then<U, F>(self, f: F) -> U where
// F: FnOnce(T) -> U,
// {
// f(*self.ptr)
// }
//}
//
//impl<T> Deref for P<T> {
// type Target = T;
//
// fn deref<'a>(&'a self) -> &'a T {
// &*self.ptr
// }
//}
//
//impl<T> DerefMut for P<T> {
// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
// &mut *self.ptr
// }
//}
//
//impl<T: 'static + Clone> Clone for P<T> {
// fn clone(&self) -> P<T> {
// P((**self).clone())
// }
//}
//
//impl<T: PartialEq> PartialEq for P<T> {
// fn eq(&self, other: &P<T>) -> bool {
// **self == **other
// }
//}
//
//impl<T: Eq> Eq for P<T> {}
//
//impl<T: Debug> Debug for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Debug::fmt(&**self, f)
// }
//}
//impl<T: Display> Display for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Display::fmt(&**self, f)
// }
//}
//
//impl<T> fmt::Pointer for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// fmt::Pointer::fmt(&self.ptr, f)
// }
//}
//
//impl<T: Hash> Hash for P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) {
// (**self).hash(state);
// }
//}
src/ast/types.rs
View file @
04c10e0b
...
...
@@ -6,24 +6,22 @@ use std::fmt;
use
std
::
collections
::
HashMap
;
use
std
::
sync
::
RwLock
;
#[derive(
Clone,
PartialEq,
Eq,
Debug,
Hash
)]
#[derive(
PartialEq,
Debug
)]
pub
struct
MuType
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
v
:
MuType_
}
impl
MuType
{
pub
fn
new
(
id
:
MuID
,
v
:
MuType_
)
->
MuType
{
MuType
{
id
:
id
,
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
id
),
v
:
v
}
}
}
#[derive(
Clone,
PartialEq,
Eq,
Debug,
Hash
)]
#[derive(
PartialEq,
Debug
)]
pub
enum
MuType_
{
/// int <length>
Int
(
usize
),
...
...
@@ -107,7 +105,7 @@ lazy_static! {
pub
static
ref
STRUCT_TAG_MAP
:
RwLock
<
HashMap
<
MuName
,
StructType_
>>
=
RwLock
::
new
(
HashMap
::
new
());
}
#[derive(
Clone,
PartialEq,
Eq,
Debug)]
#[derive(
Partial
Eq,
Debug)]
pub
struct
StructType_
{
tys
:
Vec
<
P
<
MuType
>>
}
...
...
@@ -325,10 +323,9 @@ macro_rules! is_type (
)
);
#[derive(
Clone,
PartialEq,
Eq,
Debug,
Hash
)]
#[derive(
PartialEq,
Debug
)]
pub
struct
MuFuncSig
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
pub
hdr
:
MuEntityHeader
,
pub
ret_tys
:
Vec
<
P
<
MuType
>>
,
pub
arg_tys
:
Vec
<
P
<
MuType
>>
}
...
...
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
04c10e0b
...
...
@@ -77,7 +77,7 @@ impl MachineCode for ASMCode {
}
fn
replace_reg
(
&
mut
self
,
from
:
MuID
,
to
:
MuID
)
{
let
to_reg_tag
:
MuName
=
backend
::
all_regs
()
[
to
]
.name
.unwrap
();
let
to_reg_tag
:
MuName
=
backend
::
all_regs
()
.get
(
&
to
)
.unwrap
()
.name
()
.unwrap
();
let
to_reg_string
=
"%"
.to_string
()
+
to_reg_tag
;
match
self
.reg_defines
.get
(
&
from
)
{
...
...
@@ -498,7 +498,7 @@ impl ASMCodeGen {
let
id
=
op
.extract_ssa_id
()
.unwrap
();
if
id
<
MACHINE_ID_END
{
// machine reg
format!
(
"%{}"
,
op
.name
.unwrap
())
format!
(
"%{}"
,
op
.name
()
.unwrap
())
}
else
{
// virtual register, use place holder
REG_PLACEHOLDER
.clone
()
...
...
@@ -921,7 +921,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jmp
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jmp {}"
,
dest_name
);
// symbolic label, we dont need to patch it
...
...
@@ -930,7 +930,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_je
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: je {}"
,
dest_name
);
let
asm
=
format!
(
"je {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -938,7 +938,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jne
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jne {}"
,
dest_name
);
let
asm
=
format!
(
"jne {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -946,7 +946,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_ja
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: ja {}"
,
dest_name
);
let
asm
=
format!
(
"ja {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -954,7 +954,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jae
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jae {}"
,
dest_name
);
let
asm
=
format!
(
"jae {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -962,7 +962,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jb
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jb {}"
,
dest_name
);
let
asm
=
format!
(
"jb {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -970,7 +970,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jbe
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jbe {}"
,
dest_name
);
let
asm
=
format!
(
"jbe {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -978,7 +978,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jg
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jg {}"
,
dest_name
);
let
asm
=
format!
(
"jg {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -986,7 +986,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jge
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jge {}"
,
dest_name
);
let
asm
=
format!
(
"jge {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -994,7 +994,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jl
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jl {}"
,
dest_name
);
let
asm
=
format!
(
"jl {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -1002,7 +1002,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn
emit_jle
(
&
mut
self
,
dest
:
&
Block
)
{
let
dest_name
=
dest
.name
.unwrap
();
let
dest_name
=
dest
.name
()
.unwrap
();
trace!
(
"emit: jle {}"
,
dest_name
);
let
asm
=
format!
(
"jle {}"
,
self
.asm_block_label
(
dest_name
));
...
...
@@ -1091,7 +1091,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
let
func
=
funcs
.get
(
&
fv
.func_id
)
.unwrap
()
.borrow
();
let
compiled_funcs
=
vm
.compiled_funcs
()
.read
()
.unwrap
();
let
cf
=
compiled_funcs
.get
(
&
fv
.id
)
.unwrap
()
.borrow
();
let
cf
=
compiled_funcs
.get
(
&
fv
.id
()
)
.unwrap
()
.borrow
();
let
code
=
cf
.mc
.emit
();
...
...
@@ -1100,7 +1100,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
let
mut
file_path
=
path
::
PathBuf
::
new
();
file_path
.push
(
EMIT_DIR
);
file_path
.push
(
func
.name
.unwrap
()
.to_string
()
+
".s"
);
file_path
.push
(
func
.name
()
.unwrap
()
.to_string
()
+
".s"
);
let
mut
file
=
match
File
::
create
(
file_path
.as_path
())
{
Err
(
why
)
=>
panic!
(
"couldn't create emission file {}: {}"
,
file_path
.to_str
()
.unwrap
(),
why
),
Ok
(
file
)
=>
file
...
...
@@ -1135,13 +1135,22 @@ pub fn emit_context(vm: &VM) {
let
globals
=
vm
.globals
()
.read
()
.unwrap
();
for
global
in
globals
.values
()
{
debug!
(
"emit global: {}"
,
global
);
let
(
size
,
align
)
=
{
let
ty_info
=
vm
.get_backend_type_info
(
&
global
.ty
);
let
alloc_ty
=
{
match
global
.v
{
Value_
::
Global
(
ref
ty
)
=>
ty
,
_
=>
panic!
(
"expected a global"
)
}
};
debug!
(
"getting type: {:?}"
,
alloc_ty
);
let
ty_info
=
vm
.get_backend_type_info
(
alloc_ty
.id
());
(
ty_info
.size
,
ty_info
.alignment
)
};
file
.write_fmt
(
format_args!
(
"
\t
{}
\n
"
,
directive_globl
(
symbol
(
global
.name
.unwrap
()))))
.unwrap
();
file
.write_fmt
(
format_args!
(
"
\t
{}
\n
"
,
directive_comm
(
symbol
(
global
.name
.unwrap
()),
size
,
align
)))
.unwrap
();
file
.write_fmt
(
format_args!
(
"
\t
{}
\n
"
,
directive_globl
(
symbol
(
global
.name
()
.unwrap
()))))
.unwrap
();
file
.write_fmt
(
format_args!
(
"
\t
{}
\n
"
,
directive_comm
(
symbol
(
global
.name
()
.unwrap
()),
size
,
align
)))
.unwrap
();
file
.write
(
"
\n
"
.as_bytes
())
.unwrap
();
}
...
...
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
04c10e0b
...
...
@@ -627,7 +627,7 @@ impl <'a> InstructionSelection {
TreeNode_
::
Value
(
ref
pv
)
=>
{
match
pv
.v
{
Value_
::
Constant
(
_
)
|
Value_
::
Global
|
Value_
::
Global
(
_
)
|
Value_
::
Memory
(
_
)
=>
panic!
(
"expected ireg"
),
Value_
::
SSAVar
(
_
)
=>
{
pv
.clone
()
...
...
@@ -668,8 +668,7 @@ impl <'a> InstructionSelection {
TreeNode_
::
Value
(
ref
pv
)
=>
{
match
pv
.v
{
Value_
::
SSAVar
(
_
)
=>
P
(
Value
{
id
:
vm
.next_id
(),
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
vm
.next_id
()),
ty
:
types
::
get_referent_ty
(
&
pv
.ty
)
.unwrap
(),
v
:
Value_
::
Memory
(
MemoryLocation
::
Address
{
base
:
pv
.clone
(),
...
...
@@ -678,19 +677,18 @@ impl <'a> InstructionSelection {
scale
:
None
})
}),
Value_
::
Global
=>
{
Value_
::
Global
(
_
)
=>
{
if
vm
.is_running
()
{
// get address from vm
unimplemented!
()
}
else
{
// symbolic
P
(
Value
{
id
:
vm
.next_id
(),
name
:
None
,
hdr
:
MuEntityHeader
::
unnamed
(
vm
.next_id
()),
ty
:
types
::
get_referent_ty
(
&
pv
.ty
)
.unwrap
(),
v
:
Value_
::
Memory
(
MemoryLocation
::
Symbolic
{
base
:
Some
(
x86_64
::
RIP
.clone
()),
label
:
pv
.name
.unwrap
()
label
:
pv
.name
()
.unwrap
()
})
})
}
...
...
@@ -805,7 +803,7 @@ impl CompilerPass for InstructionSelection {
fn
visit_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
for
block_id
in
func
.block_trace
.as_ref
()
.unwrap
()
{
let
block
=
func
.content
.as_ref
()
.unwrap
()
.get_block
(
*
block_id
);
let
block_label
=
block
.name
.unwrap
();
let
block_label
=
block
.name
()
.unwrap
();
self
.backend
.start_block
(
block_label
);
...
...
@@ -833,7 +831,7 @@ impl CompilerPass for InstructionSelection {
let
mc
=
self
.backend
.finish_code
();
let
compiled_func
=
CompiledFunction
{
func_id
:
func
.func_id
,
func_ver_id
:
func
.id
,
func_ver_id
:
func
.id
()
,
temps
:
HashMap
::
new
(),
mc
:
mc
};
...
...
src/compiler/backend/arch/x86_64/mod.rs
View file @
04c10e0b
...
...
@@ -16,13 +16,14 @@ use ast::ir::*;
use
ast
::
types
::
*
;
use
compiler
::
backend
::
RegGroup
;
use
std
::
collections
::
HashMap
;
macro_rules!
GPR
{
(
$name
:
expr
)
=>
{
{
let
id
=
new_machine_id
();
P
(
Value
{
id
:
id
,
name
:
Some
(
$name
),