Old, incomplete, broken stuff from a month ago.
parent
d9edbab10c
commit
894c10903c
26
src/ir.c
26
src/ir.c
|
@ -103,16 +103,17 @@ var push_var(reg reg) {
|
|||
}
|
||||
|
||||
void load_args(struct label* label, var* args) {
|
||||
struct stack_frame* dest_frame = &stack_frames[label->frame];
|
||||
struct stack_frame* dest_frame = &stack_frames[label->frame - 1];
|
||||
uint32_t depth_diff = stack_depth - dest_frame->depth;
|
||||
if (depth_diff > 0) {
|
||||
// FIXME: should be immX!!!
|
||||
x86_inst_add_r64_imm8(SP, depth_diff);
|
||||
x86_inst_add_r64_imm8(SP, depth_diff * 8);
|
||||
}
|
||||
for (uint32_t arg = 0; arg < label->argc; arg++) {
|
||||
load_var(AX, args[arg]);
|
||||
x86_inst_push_r64(AX);
|
||||
}
|
||||
stack_depth = dest_frame->depth + label->argc;
|
||||
}
|
||||
|
||||
void jump(label l, var* args) {
|
||||
|
@ -126,20 +127,15 @@ void jump_table(size_t branches, label* labels, var index, var* args) {
|
|||
assert(0); // UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void jump_if(label l, var cond, var* args) {
|
||||
struct label* label = &labels[l];
|
||||
printf("JUMP_IF %i (%i)\n", l, label->argc);
|
||||
void jump_if(label t, label e, var cond, var* args) {
|
||||
struct label* then = &labels[t];
|
||||
struct label* else_ = &labels[e];
|
||||
printf("JUMP_IF %i ELSE %i (%i)\n", t, e, then->argc);
|
||||
assert(then->argc == else_->argc && then->frame == else_->frame);
|
||||
load_var(BX, cond);
|
||||
load_args(label, args);
|
||||
inst_jump_if_not_zero(label->symbol, BX);
|
||||
}
|
||||
|
||||
void jump_unless(label l, var cond, var* args) {
|
||||
struct label* label = &labels[l];
|
||||
printf("JUMP_UNLESS %i (%i)\n", l, label->argc);
|
||||
load_var(BX, cond);
|
||||
load_args(label, args);
|
||||
inst_jump_if_zero(label->symbol, BX);
|
||||
load_args(then, args);
|
||||
inst_jump_if_not_zero(then->symbol, BX);
|
||||
inst_jump(else_->symbol);
|
||||
}
|
||||
|
||||
var lit(uint64_t lit) {
|
||||
|
|
41
src/ir.h
41
src/ir.h
|
@ -7,6 +7,40 @@
|
|||
typedef uint32_t var;
|
||||
typedef uint32_t label;
|
||||
|
||||
struct jump_target {
|
||||
label label;
|
||||
var* args;
|
||||
};
|
||||
|
||||
/// Declare a new label in the current scope with the provided number
|
||||
/// of arguments.
|
||||
///
|
||||
/// Local variables (not part of a stack frame generated by `define` or `enter`)
|
||||
/// will not be in scope of the definition of the label.
|
||||
label declare(uint32_t argc);
|
||||
|
||||
/// Define a label and create a new scope for local variables.
|
||||
///
|
||||
/// The new scope will have access to all of the variables
|
||||
/// of the parent scope of the label and the label's arguments,
|
||||
/// but not any local variables from previous definitions.
|
||||
void define(label label, var* args);
|
||||
|
||||
/// Create a new scope which encompasses all local variables defined up to this point.
|
||||
///
|
||||
/// This allows nested definitions to have access to local variables.
|
||||
void enter(void);
|
||||
|
||||
/// Jump to label, unconditionally. Ends the continuation.
|
||||
void jump(struct jump_target dest);
|
||||
|
||||
/// Jump to `then` if `cond` is not zero; jump to `else` otherwise.
|
||||
/// Ends the continuation.
|
||||
void jump_if(struct jump_target then, struct jump_target else_, var cond);
|
||||
|
||||
/// Jump to the `index`th destination. Ends the continuation.
|
||||
void jump_table(uint32_t destc, struct jump_target* destinations, var index);
|
||||
|
||||
/// Call this at the beginning of execution.
|
||||
/// It performs initialization and stuff.
|
||||
void init_ir(var* argc, var* argv, var* env);
|
||||
|
@ -61,11 +95,8 @@ void jump(label label, var* args);
|
|||
/// `index` must not be out of bounds.
|
||||
void jump_table(size_t branches, label* labels, var index, var* args);
|
||||
|
||||
/// Jump to label if `cond` is not zero.
|
||||
void jump_if(label label, var cond, var* args);
|
||||
|
||||
/// Jump to label if `cond` is zero.
|
||||
void jump_unless(label label, var cond, var* args);
|
||||
/// Jump to `then` if cond is not zero, `else` if cond is zero.
|
||||
void jump_if(label then, label else_, var cond, var* args);
|
||||
|
||||
/// Integer literal.
|
||||
var lit(uint64_t lit);
|
||||
|
|
|
@ -473,8 +473,7 @@ void exit_expr(void) {
|
|||
case IF_CRUMB: {
|
||||
struct if_crumb* ifc = &ctx->data.if_;
|
||||
assert(ifc->state == IF_COND);
|
||||
jump_unless(ifc->else_, ret, NULL);
|
||||
//jump(ifc->then_, NULL);
|
||||
jump_if(ifc->then, ifc->else_, ret, NULL);
|
||||
ifc->state = IF_THEN;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue