Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mu
mu-impl-fast
Commits
34025009
Commit
34025009
authored
Aug 17, 2017
by
qinsoon
Browse files
refactored callconvention code out of instruction selection for x64
parent
223c9d0e
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
src/ast/src/inst.rs
View file @
34025009
...
...
@@ -959,6 +959,9 @@ pub enum MemoryOrder {
SeqCst
}
pub
const
C_CALL_CONVENTION
:
CallConvention
=
CallConvention
::
Foreign
(
ForeignFFI
::
C
);
pub
const
MU_CALL_CONVENTION
:
CallConvention
=
CallConvention
::
Mu
;
#[derive(Copy,
Clone,
Debug)]
pub
enum
CallConvention
{
Mu
,
...
...
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
34025009
...
...
@@ -15,7 +15,6 @@
#![allow(unused_variables)]
use
compiler
::
backend
::
AOT_EMIT_CONTEXT_FILE
;
use
compiler
::
backend
::
AOT_EMIT_SYM_TABLE_FILE
;
use
compiler
::
backend
::
RegGroup
;
use
utils
::
ByteSize
;
use
utils
::
Address
;
...
...
src/compiler/backend/arch/x86_64/callconv.rs
0 → 100644
View file @
34025009
use
ast
::
ir
::
*
;
use
ast
::
ptr
::
*
;
use
ast
::
types
::
*
;
use
compiler
::
backend
::
RegGroup
;
use
compiler
::
backend
::
x86_64
;
#[derive(Clone,
Debug)]
pub
enum
CallConvResult
{
GPR
(
P
<
Value
>
),
GPREX
(
P
<
Value
>
,
P
<
Value
>
),
FPR
(
P
<
Value
>
),
STACK
}
pub
mod
mu
{
pub
use
super
::
c
::
*
;
}
pub
mod
c
{
use
super
::
*
;
pub
fn
compute_arguments
(
sig
:
&
MuFuncSig
)
->
Vec
<
CallConvResult
>
{
let
mut
ret
=
vec!
[];
let
mut
gpr_arg_count
=
0
;
let
mut
fpr_arg_count
=
0
;
for
ty
in
sig
.arg_tys
.iter
()
{
let
arg_reg_group
=
RegGroup
::
get_from_ty
(
ty
);
if
arg_reg_group
==
RegGroup
::
GPR
{
if
gpr_arg_count
<
x86_64
::
ARGUMENT_GPRS
.len
()
{
let
arg_gpr
=
{
let
ref
reg64
=
x86_64
::
ARGUMENT_GPRS
[
gpr_arg_count
];
let
expected_len
=
ty
.get_int_length
()
.unwrap
();
x86_64
::
get_alias_for_length
(
reg64
.id
(),
expected_len
)
};
ret
.push
(
CallConvResult
::
GPR
(
arg_gpr
));
gpr_arg_count
+=
1
;
}
else
{
// use stack to pass argument
ret
.push
(
CallConvResult
::
STACK
);
}
}
else
if
arg_reg_group
==
RegGroup
::
GPREX
{
// 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
();
ret
.push
(
CallConvResult
::
GPREX
(
arg_gpr1
,
arg_gpr2
));
gpr_arg_count
+=
2
;
}
else
{
ret
.push
(
CallConvResult
::
STACK
);
}
}
else
if
arg_reg_group
==
RegGroup
::
FPR
{
if
fpr_arg_count
<
x86_64
::
ARGUMENT_FPRS
.len
()
{
let
arg_fpr
=
x86_64
::
ARGUMENT_FPRS
[
fpr_arg_count
]
.clone
();
ret
.push
(
CallConvResult
::
FPR
(
arg_fpr
));
fpr_arg_count
+=
1
;
}
else
{
ret
.push
(
CallConvResult
::
STACK
);
}
}
else
{
// fp const, struct, etc
unimplemented!
();
}
}
ret
}
pub
fn
compute_return_values
(
sig
:
&
MuFuncSig
)
->
Vec
<
CallConvResult
>
{
let
mut
ret
=
vec!
[];
let
mut
gpr_ret_count
=
0
;
let
mut
fpr_ret_count
=
0
;
for
ty
in
sig
.ret_tys
.iter
()
{
if
RegGroup
::
get_from_ty
(
ty
)
==
RegGroup
::
GPR
{
if
gpr_ret_count
<
x86_64
::
RETURN_GPRS
.len
()
{
let
ret_gpr
=
{
let
ref
reg64
=
x86_64
::
RETURN_GPRS
[
gpr_ret_count
];
let
expected_len
=
ty
.get_int_length
()
.unwrap
();
x86_64
::
get_alias_for_length
(
reg64
.id
(),
expected_len
)
};
ret
.push
(
CallConvResult
::
GPR
(
ret_gpr
));
gpr_ret_count
+=
1
;
}
else
{
// get return value by stack
ret
.push
(
CallConvResult
::
STACK
);
}
}
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
();
ret
.push
(
CallConvResult
::
GPREX
(
ret_gpr1
,
ret_gpr2
));
}
else
{
ret
.push
(
CallConvResult
::
STACK
);
}
}
else
if
RegGroup
::
get_from_ty
(
ty
)
==
RegGroup
::
FPR
{
// floating point register
if
fpr_ret_count
<
x86_64
::
RETURN_FPRS
.len
()
{
let
ref
ret_fpr
=
x86_64
::
RETURN_FPRS
[
fpr_ret_count
];
ret
.push
(
CallConvResult
::
FPR
(
ret_fpr
.clone
()));
fpr_ret_count
+=
1
;
}
else
{
ret
.push
(
CallConvResult
::
STACK
);
}
}
else
{
// other type of return alue
unimplemented!
()
}
}
ret
}
}
\ No newline at end of file
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
34025009
This diff is collapsed.
Click to expand it.
src/compiler/backend/arch/x86_64/mod.rs
View file @
34025009
...
...
@@ -26,6 +26,9 @@ use compiler::backend::x86_64::codegen::CodeGenerator;
mod
asm_backend
;
use
compiler
::
backend
::
x86_64
::
asm_backend
::
ASMCodeGen
;
/// call conventions
pub
mod
callconv
;
// re-export a few functions for AOT compilation
#[cfg(feature
=
"aot"
)]
pub
use
compiler
::
backend
::
x86_64
::
asm_backend
::
emit_code
;
...
...
src/linkutils/aot.rs
View file @
34025009
...
...
@@ -22,8 +22,6 @@ use compiler::backend;
use
std
::
path
::
PathBuf
;
use
std
::
process
::
Command
;
use
std
::
process
::
Stdio
;
use
std
::
process
::
Output
;
/// links generated code for the given functions, static library of Zebu,
/// and a main function to produce an executable of the given name
...
...
tests/test_compiler/test_regalloc.rs
View file @
34025009
...
...
@@ -1424,7 +1424,13 @@ fn create_empty_func_foo6(vm: &VM) {
RET
);
define_block!
((
vm
,
foo6_v1
)
blk_entry
()
{
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t0
);
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t1
);
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t2
);
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t3
);
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t4
);
ssa!
((
vm
,
foo6_v1
)
<
int64
>
t5
);
define_block!
((
vm
,
foo6_v1
)
blk_entry
(
t0
,
t1
,
t2
,
t3
,
t4
,
t5
)
{
blk_entry_ret
});
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment