-
Notifications
You must be signed in to change notification settings - Fork 15
Milestone: Compile a complete function #1
Comments
I will start working on that, slowly though! Can we limit the scope to just linux/mac (systemv calling conv) for now? |
Sounds good! And yeah, we can just support one calling convention for now. As long as we keep platform-specific things reasonably localized, we can easily add more platforms later. |
|
@pepyakin as long as you specify the ABI properly when transmuting to function pointers (which you should be doing anyway), you should be able to make it work on all x64 targets with a single calling convention. You can use the system V AMD64 abi on Windows in rust without issues. |
(2.) Yes, either way would work for now. I have a mild preference for using RSP here because that will oblige us to always keep track of RSP as we add more code, which will make it easier to do things like frame pointer elimination or dynamically-aligned stack frames in the future. But I'm ok keeping it simpler for now too. (4.) Yeah, that's fine for now. It might be a good idea to start a list of these kinds of things somewhere, as they would be good discrete projects for someone looking to get involved to pick up. |
Oops, sorry, I editted a question meanwhile. Can you update your answer, @sunfishcode ? |
Ok, numbering updated :-). (3.) Yes, this is similar to (2.); if we track where RSP is, we can adjust it back, but if we have RBP, we can use that instead. Either way works. (1.) Ah, you're right, we will need to know the function's signature for this milestone. Then the simplest way to achieve our first milestone here then would be to just assume the signature is The step I was picturing we'd do in a later milestone is to have translate_sections collect up the types and functions into a rudimentary |
Let's start by working to compile this function into machine code. The steps are:
function_body::translate
, to write a function that maps from local indices to offsets in that region, and to compute the needed size of that region.Registers
struct into a backendContext
, add a field recording the current depth of the stack pointer, and makepush_i32
andpop_i32
subtract from and add to this field so that we always know where the stack pointer is (relative to where it started).mov offset(%rsp), Rq(op)
whereoffset
is the offset within the locals area plus the current stack depth.where
framesize
is the size of the locals area.Store the incoming function arguments into their slots in the locals area. If you're on Linux/Mac/etc., the first 4 arguments are in
rdi
,rsi
,rdx
,rcx
. If you're on Windows, they're inrcx
,rdx
,r8
,r9
. Eventually we'll want to make the calling convention configurable, but it's ok to hardcode stuff to get started with.Implement returns - at the function exit, pop the last remaining
i32
, copy it into RAX, add the size of the locals area back to the stack pointer, then do aret
.function_body::translate
, instead of just disassembling the output, return the compiled code, make examples/test.rs transmute the address to a function pointer and... call it!Once that milestone is achieved, the work can branch out a little bit. One set of tasks is implementing more integer arithmetic operations. Another is to add floating-point register support and after that, floating-point arithmetic operations. And independently of those, the next big milestone will be to compile a fibonacci function. Once we achieve this first milestone, I'll write up a new design issue for that :-).
For anyone interested in getting involved, welcome! and please post in the issue here so that we can coordinate work.
The text was updated successfully, but these errors were encountered: