Hello. Following patch adds support for HSAIL emission on the pair of builtins.
Martin
>From 4bb6a85f805dd7cab4f4a2ce7f148803214e5a9e Mon Sep 17 00:00:00 2001 From: mliska <mli...@suse.cz> Date: Fri, 4 Sep 2015 16:29:21 +0200 Subject: [PATCH 4/7] HSA: add support for __builtin_mem{set,cpy}. gcc/ChangeLog: 2015-09-04 Martin Liska <mli...@suse.cz> * hsa-gen.c (build_memset_value): New function. (gen_hsa_memory_set): New function. (gen_hsa_insns_for_call): Add support for __builtin_memcpy and __builtin_memset. --- gcc/hsa-gen.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index cf43189..7796895 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -2123,6 +2123,59 @@ gen_hsa_memory_copy (hsa_bb *hbb, hsa_op_address *target, hsa_op_address *src, } } +/* Create a memset mask that is created by copying a CONSTANT byte value + to an integer of BYTE_SIZE bytes. */ + +static unsigned HOST_WIDE_INT +build_memset_value (unsigned HOST_WIDE_INT constant, unsigned byte_size) +{ + HOST_WIDE_INT v = constant; + + for (unsigned i = 1; i < byte_size; i++) + v |= constant << (8 * i); + + return v; +} + +/* Generate memory set instructions that are going to be used + for setting a CONSTANT byte value to TARGET memory of SIZE bytes. */ + +static void +gen_hsa_memory_set (hsa_bb *hbb, hsa_op_address *target, + unsigned HOST_WIDE_INT constant, + unsigned size) +{ + hsa_op_address *addr; + hsa_insn_mem *mem; + + unsigned offset = 0; + + while (size) + { + unsigned s; + if (size >= 8) + s = 8; + else if (size >= 4) + s = 4; + else if (size >= 2) + s = 2; + else + s = 1; + + addr = new hsa_op_address (target->symbol, target->reg, + target->imm_offset + offset); + + BrigType16_t t = get_integer_type_by_bytes (s, false); + HOST_WIDE_INT c = build_memset_value (constant, s); + + mem = new hsa_insn_mem (BRIG_OPCODE_ST, t, new hsa_op_immed (c, t), + addr); + hbb->append_insn (mem); + offset += s; + size -= s; + } +} + /* Generate HSA instructions for a single assignment. HBB is the basic block they will be appended to. SSA_MAP maps gimple SSA names to HSA pseudo registers. */ @@ -3642,6 +3695,58 @@ specialop: break; } + case BUILT_IN_MEMCPY: + { + tree byte_size = gimple_call_arg (stmt, 2); + + if (TREE_CODE (byte_size) != INTEGER_CST) + { + sorry ("Support for HSA does not implement __builtin_memcpy with " + "a non constant size"); + return; + } + + tree dst = gimple_call_arg (stmt, 0); + tree src = gimple_call_arg (stmt, 1); + + hsa_op_address *dst_addr = gen_hsa_addr (dst, hbb, ssa_map); + hsa_op_address *src_addr = gen_hsa_addr (src, hbb, ssa_map); + unsigned n = tree_to_uhwi (byte_size); + + gen_hsa_memory_copy (hbb, dst_addr, src_addr, n); + + break; + } + case BUILT_IN_MEMSET: + { + tree c = gimple_call_arg (stmt, 1); + + if (TREE_CODE (c) != INTEGER_CST) + { + sorry ("Support for HSA does not implement __builtin_memset with " + "a non constant byte value that should be written"); + return; + } + + tree byte_size = gimple_call_arg (stmt, 2); + + if (TREE_CODE (byte_size) != INTEGER_CST) + { + sorry ("Support for HSA does not implement __builtin_memset with " + "a non constant size"); + return; + } + + hsa_op_address *dst_addr = gen_hsa_addr (gimple_call_arg (stmt, 0), + hbb, ssa_map); + unsigned n = tree_to_uhwi (byte_size); + unsigned HOST_WIDE_INT constant = tree_to_uhwi + (fold_convert (unsigned_char_type_node, c)); + + gen_hsa_memory_set (hbb, dst_addr, constant, n); + + break; + } default: sorry ("Support for HSA does not implement calls to builtin %D", gimple_call_fndecl (stmt)); -- 2.4.6