/* architecture specific floating point arithmetic mode (if any) */
static ir_mode *mode_float_arithmetic;
+/* alignment of stack parameters */
+static unsigned stack_param_align;
+
static int next_value_number_function;
static ir_node *continue_label;
static ir_node *break_label;
return size_node;
}
+/**
+ * Return a node representing the size of a type.
+ */
static ir_node *get_type_size(type_t *type)
{
type = skip_typeref(type);
return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
}
+/**
+ * Generate a pinned unary builtin.
+ *
+ * @param kind the builtin kind to generate
+ * @param op the operand
+ * @param function_type the function type for the GNU builtin routine
+ * @param db debug info
+ */
+static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db)
+{
+ ir_node *in[1];
+ in[0] = expression_to_firm(op);
+
+ ir_type *tp = get_ir_type(function_type);
+ ir_type *res = get_method_res_type(tp, 0);
+ ir_node *mem = get_store();
+ ir_node *irn = new_d_Builtin(db, mem, kind, 1, in, tp);
+ set_store(new_Proj(irn, mode_M, pn_Builtin_M));
+ return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
+}
+
+
+/**
+ * Generate an binary-void-return builtin.
+ *
+ * @param kind the builtin kind to generate
+ * @param op1 the first operand
+ * @param op2 the second operand
+ * @param function_type the function type for the GNU builtin routine
+ * @param db debug info
+ */
+static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1, expression_t *op2,
+ type_t *function_type, dbg_info *db)
+{
+ ir_node *in[2];
+ in[0] = expression_to_firm(op1);
+ in[1] = expression_to_firm(op2);
+
+ ir_type *tp = get_ir_type(function_type);
+ ir_node *mem = get_store();
+ ir_node *irn = new_d_Builtin(db, mem, kind, 2, in, tp);
+ set_store(new_Proj(irn, mode_M, pn_Builtin_M));
+ return NULL;
+}
+
/**
* Transform calls to builtin functions.
*/
case bk_ms_byteswap_ulong:
case bk_ms_byteswap_uint64:
return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi);
+ case bk_ms__inbyte:
+ case bk_ms__inword:
+ case bk_ms__indword:
+ return gen_unary_builtin_pinned(ir_bk_inport, call->arguments->expression, function_type, dbgi);
+ case bk_ms__outbyte:
+ case bk_ms__outword:
+ case bk_ms__outdword:
+ return gen_binary_builtin_mem(ir_bk_outport, call->arguments->expression,
+ call->arguments->next->expression, function_type, dbgi);
default:
panic("unsupported builtin found");
}
new_d_simpleSel(dbgi, no_mem, arg_base, parm_ent);
ir_node *const cnst = get_type_size(expr->parameter->base.type);
- ir_node *const add = new_d_Add(dbgi, arg_sel, cnst, mode_P_data);
+ ir_mode *const mode = get_irn_mode(cnst);
+ ir_node *const c1 = new_Const_long(mode, stack_param_align - 1);
+ ir_node *const c2 = new_d_Add(dbgi, cnst, c1, mode);
+ ir_node *const c3 = new_Const_long(mode, -(long)stack_param_align);
+ ir_node *const c4 = new_d_And(dbgi, c2, c3, mode);
+ ir_node *const add = new_d_Add(dbgi, arg_sel, c2, mode_P_data);
set_value_for_expression(expr->ap, add);
return NULL;
ir_node *const res = deref_address(dbgi, type, ap);
ir_node *const cnst = get_type_size(expr->base.type);
- ir_node *const add = new_d_Add(dbgi, ap, cnst, mode_P_data);
+ ir_mode *const mode = get_irn_mode(cnst);
+ ir_node *const c1 = new_Const_long(mode, stack_param_align - 1);
+ ir_node *const c2 = new_d_Add(dbgi, cnst, c1, mode);
+ ir_node *const c3 = new_Const_long(mode, -(long)stack_param_align);
+ ir_node *const c4 = new_d_And(dbgi, c2, c3, mode);
+ ir_node *const add = new_d_Add(dbgi, ap, c4, mode_P_data);
set_value_for_expression_addr(ap_expr, add, ap_addr);
if (function->kind != EXPR_REFERENCE)
return false;
reference_expression_t *ref = &function->reference;
- if (ref->entity->kind == ENTITY_FUNCTION &&
+ if (ref->entity->kind != ENTITY_FUNCTION ||
ref->entity->function.btk != bk_gnu_builtin_expect)
return false;
const backend_params *be_params = be_get_backend_param();
mode_float_arithmetic = be_params->mode_float_arithmetic;
+
+ stack_param_align = be_params->stack_param_align;
}
void exit_ast2firm(void)