more tests passing

extensions
Steven Massey 5 years ago
parent 4c01ba4ba7
commit 16e62cd360

@ -534,6 +534,24 @@ M3Result AddTrapRecord (IM3Compilation o)
return result; return result;
} }
void PatchBranches (IM3Compilation o)
{
M3CompilationScope * block = & o->block;
pc_t pc = GetPC (o);
while (block->patches)
{ m3log (compile, "patching location: %p to pc: %p", block->patches->location, pc);
IM3BranchPatch next = block->patches->next;
pc_t * location = block->patches->location;
* location = pc;
m3Free (block->patches);
block->patches = next;
}
}
//------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------
@ -764,6 +782,8 @@ _ (Pop (o));
_ (EmitOp (o, op_Return)); _ (EmitOp (o, op_Return));
o->block.isPolymorphic = true;
_catch: return result; _catch: return result;
} }
@ -773,12 +793,14 @@ M3Result Compile_Else_End (IM3Compilation o, u8 i_opcode)
{ {
M3Result result = c_m3Err_none; M3Result result = c_m3Err_none;
// function end:
if (o->block.depth == 0) if (o->block.depth == 0)
{ {
PatchBranches (o);
if (o->block.type) if (o->block.type)
{ {
// expression block w/ implicit return // if (GetStackTopType (o) != c_m3Type_none)
if (GetStackTopType (o) != c_m3Type_none)
_ (ReturnStackTop (o)); _ (ReturnStackTop (o));
} }
@ -935,7 +957,7 @@ _ (EmitOp (o, op));
{ {
bool conditionInRegister = IsStackTopInRegister (o); bool conditionInRegister = IsStackTopInRegister (o);
op = conditionInRegister ? op_BranchIf_r : op_BranchIf_s; // no block type or fp block type op = conditionInRegister ? op_BranchIf_r : op_BranchIf_s;
conditionSlot = GetStackTopSlotIndex (o); conditionSlot = GetStackTopSlotIndex (o);
_ (Pop (o)); // condition _ (Pop (o)); // condition
@ -947,11 +969,15 @@ _ (MoveStackTopToRegister (o));
} }
else if (IsIntType (valueType)) else if (IsIntType (valueType))
{ {
valueSlot = GetStackTopSlotIndex (o); // need to deal with int value in slot. it needs to be copied to _r0 during the branch
if (IsStackTopInSlot (o))
const IM3Operation ifOps [2][2] = { { op_i32_BranchIf_ss, op_i32_BranchIf_rs }, { op_i64_BranchIf_ss, op_i64_BranchIf_rs } }; {
valueSlot = GetStackTopSlotIndex (o);
op = ifOps [valueType - c_m3Type_i32] [conditionInRegister];
const IM3Operation ifOps [2][2] = { { op_i32_BranchIf_ss, op_i32_BranchIf_rs }, { op_i64_BranchIf_ss, op_i64_BranchIf_rs } };
op = ifOps [valueType - c_m3Type_i32] [conditionInRegister];
}
} }
} }
else else
@ -976,7 +1002,6 @@ _ (EmitOp (o, op));
_ (m3Alloc (& scope->patches, M3BranchPatch, 1)); _ (m3Alloc (& scope->patches, M3BranchPatch, 1));
// printf ("scope: %p -- attach patch: %p to %p \n", scope, scope->patches, patch);
scope->patches->location = (pc_t *) ReservePointer (o); scope->patches->location = (pc_t *) ReservePointer (o);
scope->patches->next = patch; scope->patches->next = patch;
} }
@ -1459,7 +1484,7 @@ const M3OpInfo c_operations [] =
M3OP( "end", 0, none, d_emptyOpList(), Compile_Else_End ), // 0x0b M3OP( "end", 0, none, d_emptyOpList(), Compile_Else_End ), // 0x0b
M3OP( "br", 0, none, d_singleOp (Branch), Compile_Branch ), // 0x0c M3OP( "br", 0, none, d_singleOp (Branch), Compile_Branch ), // 0x0c
M3OP( "br_if", -1, none, op_BranchIf_r, op_BranchIf_r, NULL, Compile_Branch ), // 0x0d M3OP( "br_if", -1, none, op_BranchIf_r, op_BranchIf_s, NULL, Compile_Branch ), // 0x0d
M3OP( "br_table", -1, none, d_singleOp (BranchTable), Compile_BranchTable ), // 0x0e M3OP( "br_table", -1, none, d_singleOp (BranchTable), Compile_BranchTable ), // 0x0e
M3OP( "return", 0, any, d_singleOp (Return), Compile_Return ), // 0x0f M3OP( "return", 0, any, d_singleOp (Return), Compile_Return ), // 0x0f
M3OP( "call", 0, any, d_singleOp (Call), Compile_Call ), // 0x10 M3OP( "call", 0, any, d_singleOp (Call), Compile_Call ), // 0x10
@ -1660,7 +1685,7 @@ const M3OpInfo c_operations [] =
M3OP( "f32.reinterpret/i32", 0, f_32, d_unaryOpList(f32, Reinterpret_i32) ), // 0xbe M3OP( "f32.reinterpret/i32", 0, f_32, d_unaryOpList(f32, Reinterpret_i32) ), // 0xbe
M3OP( "f64.reinterpret/i64", 0, f_64, d_unaryOpList(f64, Reinterpret_i64) ), // 0xbf M3OP( "f64.reinterpret/i64", 0, f_64, d_unaryOpList(f64, Reinterpret_i64) ), // 0xbf
# ifdef DEBUG // for code logging: # ifdef DEBUG // for codepage logging:
M3OP( "Const", 1, any, op_Const ), M3OP( "Const", 1, any, op_Const ),
M3OP( "Entry", 0, none, op_Entry ), M3OP( "Entry", 0, none, op_Entry ),
M3OP( "Compile", 0, none, op_Compile), M3OP( "Compile", 0, none, op_Compile),
@ -1679,7 +1704,12 @@ const M3OpInfo c_operations [] =
M3OP( "SetRegister_i64", 0, none, op_SetRegister_i64), M3OP( "SetRegister_i64", 0, none, op_SetRegister_i64),
M3OP( "SetRegister_f32", 0, none, op_SetRegister_f32), M3OP( "SetRegister_f32", 0, none, op_SetRegister_f32),
M3OP( "SetRegister_f64", 0, none, op_SetRegister_f64), M3OP( "SetRegister_f64", 0, none, op_SetRegister_f64),
M3OP( "i32_BranchIf_rs", 0, none, op_i32_BranchIf_rs),
M3OP( "i32_BranchIf_ss", 0, none, op_i32_BranchIf_ss),
M3OP( "i64_BranchIf_rs", 0, none, op_i64_BranchIf_rs),
M3OP( "i64_BranchIf_ss", 0, none, op_i64_BranchIf_ss),
M3OP( "End", 0, none, op_End ), M3OP( "End", 0, none, op_End ),
# endif # endif
@ -1785,18 +1815,8 @@ _ (ValidateBlockEnd (o, & moveStackTopToRegister));
if (moveStackTopToRegister) if (moveStackTopToRegister)
_ (MoveStackTopToRegister (o)); _ (MoveStackTopToRegister (o));
pc_t pc = GetPC (o); PatchBranches (o);
while (block->patches)
{ m3log (compile, "patching location: %p to pc: %p", block->patches->location, pc);
IM3BranchPatch next = block->patches->next;
pc_t * location = block->patches->location;
* location = pc;
m3Free (block->patches);
block->patches = next;
}
o->block = outerScope; o->block = outerScope;
_catch: return result; _catch: return result;
@ -1993,7 +2013,7 @@ _ (EmitOp (o, op_Entry));//, comp.stackIndex);
EmitPointer (o, io_function); EmitPointer (o, io_function);
_ (Compile_BlockStatements (o)); _ (Compile_BlockStatements (o));
io_function->compiled = pc; io_function->compiled = pc;
u32 numConstants = o->constSlotIndex - o->firstConstSlotIndex; u32 numConstants = o->constSlotIndex - o->firstConstSlotIndex;

@ -43,7 +43,7 @@ enum
//----------------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------------
// since the end location of a block can be unknown when a branch is compiled, writing // since the end location of a block is unknown when a branch is compiled, writing
// the actual address must deferred. A linked-list of patch locations is kept in // the actual address must deferred. A linked-list of patch locations is kept in
// M3CompilationScope. When the block compilation exits, it patches these addresses. // M3CompilationScope. When the block compilation exits, it patches these addresses.
typedef struct M3BranchPatch typedef struct M3BranchPatch

@ -275,6 +275,10 @@ d_m3OpDef (Loop)
// compiled m3 code. with non-Windows calling conventions, a new // compiled m3 code. with non-Windows calling conventions, a new
// "IM3Runtime _runtime" argument could be added to operations to detach // "IM3Runtime _runtime" argument could be added to operations to detach
// the execution context from the codepage. // the execution context from the codepage.
// alternatively:
// the compiler could track whether blocks/functions contain mem.grows.
// functions that are grow-clean could be shared and those that aren't
// could be copied and patched to the requesting runtime
do do
{ {

@ -470,11 +470,11 @@ else:
"memory", "memory_trap", "memory_grow", "memory", "memory_trap", "memory_grow",
"unreachable", "unreachable",
"switch", "if", "br", "switch", "if", "br", "br_if", "loop", "block",
"nop", "start", "return", "nop", "start",
#--- TODO --- #--- TODO ---
#"loop", "labels", "block", "br_if", "br_table", "return", "unwind", #"labels", "br_table", "unwind",
#"float_exprs", #"float_exprs",
])) ]))

Loading…
Cancel
Save