X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ast2firm.c;h=be26030b24c95ccc967fea8ff0ccdfc0337efd7d;hb=a07a54193596ec41a927277852a089cc02b31eb6;hp=8ab912f904518519d40db28f189eb3fa9f1b15fb;hpb=912addb873c5f8b193970fe4f0926ff89aec3fc8;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 8ab912f..be26030 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -1570,6 +1570,51 @@ static ir_node *gen_unary_builtin(ir_builtin_kind kind, expression_t *op, type_t 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. */ @@ -1712,7 +1757,6 @@ static ir_node *process_builtin_call(const call_expression_t *call) return NULL; } case bk_ms_ReturnAddress: { - expression_t *const expression = call->arguments->expression; ir_node *in[2]; in[0] = new_Const_long(mode_int, 0); @@ -1721,6 +1765,35 @@ static ir_node *process_builtin_call(const call_expression_t *call) ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp); return new_Proj(irn, mode_P_data, pn_Builtin_1_result); } + case bk_ms_rotl: + case bk_ms_rotl64: { + ir_node *val = expression_to_firm(call->arguments->expression); + ir_node *shf = expression_to_firm(call->arguments->next->expression); + ir_mode *mode = get_irn_mode(val); + return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode); + } + case bk_ms_rotr: + case bk_ms_rotr64: { + ir_node *val = expression_to_firm(call->arguments->expression); + ir_node *shf = expression_to_firm(call->arguments->next->expression); + ir_mode *mode = get_irn_mode(val); + ir_node *c = new_Const_long(mode_uint, get_mode_size_bits(mode)); + ir_node *sub = new_d_Sub(dbgi, c, create_conv(dbgi, shf, mode_uint), mode_uint); + return new_d_Rotl(dbgi, val, sub, mode); + } + case bk_ms_byteswap_ushort: + 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"); } @@ -3352,7 +3425,7 @@ static bool is_builtin_expect(const expression_t *expression) 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;