📄 slang_assemble.c
字号:
{
assert (!"var->initializer, oper_identifier");
}
else
{
if (!reference)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->addr_tmp, 4))
return 0;
}
/* XXX: globals! */
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
size))
return 0;
if (!reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
if (!dereference (file, op, space, info))
return 0;
}
}
}
break;
case slang_oper_sequence:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
&stk))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_assign:
if (!_slang_assemble_assign (file, op, "=", reference, space, info))
return 0;
break;
case slang_oper_addassign:
if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
return 0;
break;
case slang_oper_subassign:
if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
return 0;
break;
case slang_oper_mulassign:
if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
return 0;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
return 0;
break;
case slang_oper_select:
if (!_slang_assemble_select (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalor:
if (!_slang_assemble_logicalor (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicaland:
if (!_slang_assemble_logicaland (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalxor:
if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
if (!call_function_name (file, "<", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greater:
if (!call_function_name (file, ">", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_lessequal:
if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greaterequal:
if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
if (!call_function_name (file, "+", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_subtract:
if (!call_function_name (file, "-", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_multiply:
if (!call_function_name (file, "*", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
if (!call_function_name (file, "/", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_equal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 1))
return 0;
}
break;
case slang_oper_notequal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 0))
return 0;
}
break;
case slang_oper_preincrement:
if (!_slang_assemble_assign (file, op, "++", reference, space, info))
return 0;
break;
case slang_oper_predecrement:
if (!_slang_assemble_assign (file, op, "--", reference, space, info))
return 0;
break;
case slang_oper_plus:
if (!call_function_name (file, "+", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_minus:
if (!call_function_name (file, "-", op->children, 1, 0, space, info))
return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
if (!call_function_name (file, "!", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_subscript:
{
slang_assembly_stack_info _stk;
slang_assembly_typeinfo ti_arr, ti_elem;
unsigned int arr_size = 0, elem_size = 0;
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
return 0;
slang_assembly_typeinfo_construct (&ti_arr);
if (!_slang_typeof_operation (op->children, space, &ti_arr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
slang_assembly_typeinfo_construct (&ti_elem);
if (!_slang_typeof_operation (op, space, &ti_elem))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < elem_size; i += 4)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
arr_size - elem_size + i + 4, i + 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free,
arr_size - elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
}
break;
case slang_oper_call:
{
slang_function *fun = _slang_locate_function (op->identifier, op->children,
op->num_children, space);
if (fun == NULL)
{
if (!_slang_assemble_constructor (file, op, flow, space, info))
return 0;
}
else
{
if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
return 0;
}
}
break;
case slang_oper_field:
{
slang_assembly_typeinfo ti_after, ti_before;
slang_assembly_stack_info _stk;
slang_assembly_typeinfo_construct (&ti_after);
if (!_slang_typeof_operation (op, space, &ti_after))
{
slang_assembly_typeinfo_destruct (&ti_after);
return 0;
}
slang_assembly_typeinfo_construct (&ti_before);
if (!_slang_typeof_operation (op->children, space, &ti_before))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!reference && ti_after.is_swizzled)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->swizzle_tmp, 16))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
/* TODO: inspect stk */
if (ti_after.is_swizzled)
{
if (reference)
{
if (ti_after.swz.num_components == 1)
{
if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
ti_after.swz.swizzle[0] * 4))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < ti_after.swz.num_components; i++)
stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
}
}
else
{
if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
&ti_after.spec, &ti_before.spec, info))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
}
else
{
if (reference)
{
/* TODO: struct field address */
}
else
{
/* TODO: struct field value */
}
}
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
}
break;
case slang_oper_postincrement:
if (!call_function_name_dummyint (file, "++", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
case slang_oper_postdecrement:
if (!call_function_name_dummyint (file, "--", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
default:
return 0;
}
return 1;
}
void xxx_first (slang_assembly_file *file)
{
slang_assembly_file_push (file, slang_asm_jump);
}
void xxx_prolog (slang_assembly_file *file, unsigned int addr)
{
file->code[0].param[0] = file->count;
slang_assembly_file_push_label (file, slang_asm_call, addr);
slang_assembly_file_push (file, slang_asm_exit);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -