From patchwork Wed Aug 4 09:03:00 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hariharan Sandanagobalane X-Patchwork-Id: 60836 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 70279B70A4 for ; Wed, 4 Aug 2010 19:03:16 +1000 (EST) Received: (qmail 13161 invoked by alias); 4 Aug 2010 09:03:13 -0000 Received: (qmail 12725 invoked by uid 22791); 4 Aug 2010 09:03:11 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_00, RCVD_NUMERIC_HELO, TW_CP X-Spam-Check-By: sourceware.org Received: from cartman.nzsolutions.net (HELO mail3.netzensolutions.com) (87.117.194.66) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 04 Aug 2010 09:03:04 +0000 Received: from [172.17.3.28] (localhost.localdomain [127.0.0.1]) by mail3.netzensolutions.com (Postfix) with ESMTPA id 872591248247 for ; Wed, 4 Aug 2010 10:03:00 +0100 (BST) Received: from 82.111.145.34 ([82.111.145.34] helo=[172.17.3.28]) by cartman.nzsolutions.co.uk; 4 Aug 2010 10:03:00 +0100 Message-ID: <4C592CC4.70208@picochip.com> Date: Wed, 04 Aug 2010 10:03:00 +0100 From: Hariharan Sandanagobalane User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100430 Fedora/3.0.4-3.fc13 Thunderbird/3.0.4 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [PATCH, picochip] Added movmem pattern and defined OVERRIDE_OPTIONS_AFTER_CHANGE Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello all, I have added a movmem pattern, defined OVERRIDE_OPTIONS_AFTER_CHANGE and fixed some c90 warnings on the picochip port code. Committed to mainline as r162858 Changelog: * config/picochip/picochip.c (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define. picochip_expand_movmemhi : Expand movmem pattern. * config/picochip/picochip-protos.h (picochip_expand_movmemhi) : Declare. * config/picochip/picochip.md (movmemhi) : New pattern Thanks Hari Index: gcc/config/picochip/picochip.c =================================================================== --- gcc/config/picochip/picochip.c (revision 162666) +++ gcc/config/picochip/picochip.c (working copy) @@ -301,6 +301,9 @@ #undef TARGET_STATIC_CHAIN #define TARGET_STATIC_CHAIN picochip_static_chain +#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE +#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_override_options + struct gcc_target targetm = TARGET_INITIALIZER; @@ -359,7 +362,6 @@ flag_schedule_insns_after_reload = 0; if (picochip_flag_schedule_insns2) { - if (optimize_size) picochip_schedule_type = DFA_TYPE_SPACE; else @@ -367,7 +369,6 @@ picochip_schedule_type = DFA_TYPE_SPEED; flag_delayed_branch = 0; } - } else picochip_schedule_type = DFA_TYPE_NONE; @@ -449,6 +450,73 @@ set_optab_libfunc (add_optab, DImode, "_adddi3"); set_optab_libfunc (sub_optab, DImode, "_subdi3"); } + +/* Memcpy function */ +int +picochip_expand_movmemhi (rtx *operands) +{ + rtx src_addr_reg, dst_addr_reg, count_reg, src_mem, dst_mem, tmp_reg; + rtx start_label; + int align, size; + src_addr_reg = gen_reg_rtx(HImode); + dst_addr_reg = gen_reg_rtx(HImode); + count_reg = gen_reg_rtx(HImode); + emit_insn (gen_movhi (count_reg, operands[2])); + emit_insn (gen_movqi (src_addr_reg, XEXP(operands[1], 0))); + emit_insn (gen_movqi (dst_addr_reg, XEXP(operands[0], 0))); + gcc_assert (GET_CODE(count_reg) == REG); + start_label = gen_label_rtx (); + emit_label (start_label); + + /* We can specialise the code for different alignments */ + align = INTVAL(operands[3]); + size = INTVAL(operands[2]); + gcc_assert(align >= 0 && size >= 0); + if (size != 0) + { + if (size % 4 == 0 && align % 4 == 0) + { + src_mem = gen_rtx_MEM(SImode, src_addr_reg); + dst_mem = gen_rtx_MEM(SImode, dst_addr_reg); + tmp_reg = gen_reg_rtx(SImode); + emit_insn (gen_movsi (tmp_reg, src_mem)); + emit_insn (gen_movsi (dst_mem, tmp_reg)); + emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, GEN_INT(4))); + emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, GEN_INT(4))); + emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-4))); + /* The sub instruction above generates cc, but we cannot just emit the branch.*/ + emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); + } + else if (size % 2 == 0 && align % 2 == 0) + { + src_mem = gen_rtx_MEM(HImode, src_addr_reg); + dst_mem = gen_rtx_MEM(HImode, dst_addr_reg); + tmp_reg = gen_reg_rtx(HImode); + emit_insn (gen_movhi (tmp_reg, src_mem)); + emit_insn (gen_movhi (dst_mem, tmp_reg)); + emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, const2_rtx)); + emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, const2_rtx)); + emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-2))); + /* The sub instruction above generates cc, but we cannot just emit the branch.*/ + emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); + } + else + { + src_mem = gen_rtx_MEM(QImode, src_addr_reg); + dst_mem = gen_rtx_MEM(QImode, dst_addr_reg); + tmp_reg = gen_reg_rtx(QImode); + emit_insn (gen_movqi (tmp_reg, src_mem)); + emit_insn (gen_movqi (dst_mem, tmp_reg)); + emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, const1_rtx)); + emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, const1_rtx)); + emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-1))); + /* The sub instruction above generates cc, but we cannot just emit the branch.*/ + emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); + } + } + return 1; +} + /* Return the register class for letter C. */ enum reg_class @@ -523,9 +591,9 @@ picochip_return_addr_rtx(int count, rtx frameaddr ATTRIBUTE_UNUSED) { if (count==0) - return gen_rtx_REG (Pmode, LINK_REGNUM); + return gen_rtx_REG (Pmode, LINK_REGNUM); else - return NULL_RTX; + return NULL_RTX; } @@ -1150,11 +1218,11 @@ } int -picochip_class_max_nregs (int class, int mode) +picochip_class_max_nregs (int reg_class, int mode) { int size = ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); - if (class == ACC_REGS) + if (reg_class == ACC_REGS) return 1; if (GET_MODE_CLASS (mode) == MODE_CC) @@ -1339,11 +1407,12 @@ picochip_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode) { + unsigned mask_val; + if (!optimize) return x; - unsigned mask_val; - // Depending on mode, the offsets allowed are either 16/32/64. + /* Depending on mode, the offsets allowed are either 16/32/64.*/ switch (mode) { case QImode: @@ -1363,12 +1432,13 @@ && GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) == CONST_INT) { - int offset = INTVAL (XEXP (x, 1)); + int high_val, low_val, offset; + offset = INTVAL (XEXP (x, 1)); // Ignore cases with negative offsets. if (offset < 0) return x; - int high_val = offset & mask_val; - int low_val = offset - high_val; + high_val = offset & mask_val; + low_val = offset - high_val; if (high_val != 0) { rtx temp_reg = force_reg (Pmode, gen_rtx_PLUS (Pmode, XEXP (x, 0), GEN_INT(high_val))); @@ -1398,6 +1468,8 @@ int opnum, int type, int ind_levels ATTRIBUTE_UNUSED) { + unsigned mask_val; + if (picochip_symbol_offset(*x)) { *x = gen_rtx_CONST(mode, *x); @@ -1419,7 +1491,6 @@ return 1; } - unsigned mask_val; // Depending on mode, the offsets allowed are either 16/32/64. switch (mode) { @@ -1440,12 +1511,13 @@ && GET_CODE (XEXP (*x, 0)) == REG && GET_CODE (XEXP (*x, 1)) == CONST_INT) { - int offset = INTVAL (XEXP (*x, 1)); + int high_val, low_val, offset; + offset = INTVAL (XEXP (*x, 1)); // Ignore cases with negative offsets. if (offset < 0) return 0; - int high_val = offset & mask_val; - int low_val = offset - high_val; + high_val = offset & mask_val; + low_val = offset - high_val; if (high_val != 0) { rtx temp_reg = gen_rtx_PLUS (Pmode, XEXP (*x, 0), GEN_INT(high_val)); @@ -1637,7 +1709,7 @@ for (i = 0; i < length; ++i) { - fprintf (file, "16#%hhx# ", (char) (str[i])); + fprintf (file, "16#%x# ", (char) (str[i])); } fprintf (file, " ; "); @@ -2240,6 +2312,7 @@ const char * picochip_output_compare (rtx operands[]) { + int code; if (HImode != GET_MODE (operands[1]) || (HImode != GET_MODE (operands[2]) && @@ -2249,9 +2322,9 @@ __FUNCTION__); } + code = GET_CODE (operands[0]); /* Use the type of comparison to output the appropriate condition test. */ - int code = GET_CODE (operands[0]); switch (code) { case NE: @@ -3580,6 +3653,7 @@ { int offset1=0,offset2=0; rtx reg; + rtx address; if (GET_CODE(XEXP(opnd1,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd1,0),1)) == CONST_INT) { offset1 = INTVAL(XEXP(XEXP(opnd1,0),1)); @@ -3593,7 +3667,7 @@ { offset2 = INTVAL(XEXP(XEXP(opnd2,0),1)); } - rtx address = gen_rtx_PLUS (HImode, reg, GEN_INT(minimum(offset1,offset2))); + address = gen_rtx_PLUS (HImode, reg, GEN_INT(minimum(offset1,offset2))); return gen_rtx_MEM(SImode,address); } @@ -4033,6 +4107,7 @@ picochip_generate_halt (void) { static int currentId = 0; + rtx insns; rtx id = GEN_INT (currentId); currentId += 1; @@ -4043,7 +4118,7 @@ it has to continue execution after the HALT.*/ emit_barrier (); - rtx insns = get_insns(); + insns = get_insns(); end_sequence(); emit_insn (insns); @@ -4056,6 +4131,7 @@ void picochip_init_builtins (void) { + tree noreturn; tree endlink = void_list_node; tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink); @@ -4197,7 +4273,7 @@ /* Halt instruction. Note that the builtin function is marked as having the attribute `noreturn' so that the compiler realises that the halt stops the program dead. */ - tree noreturn = tree_cons (get_identifier ("noreturn"), NULL, NULL); + noreturn = tree_cons (get_identifier ("noreturn"), NULL, NULL); add_builtin_function ("__builtin_halt", void_ftype_void, PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL, noreturn); Index: gcc/config/picochip/picochip-protos.h =================================================================== --- gcc/config/picochip/picochip-protos.h (revision 162666) +++ gcc/config/picochip/picochip-protos.h (working copy) @@ -46,6 +46,8 @@ extern const char *picochip_output_testport_array (int alternative, rtx operands[]); +extern int picochip_expand_movmemhi (rtx *operands); + extern rtx gen_SImode_mem(rtx opnd1,rtx opnd2); extern bool ok_to_peephole_stw(rtx opnd0, rtx opnd1, rtx opnd2, rtx opnd3); extern bool ok_to_peephole_ldw(rtx opnd0, rtx opnd1, rtx opnd2, rtx opnd3); Index: gcc/config/picochip/picochip.md =================================================================== --- gcc/config/picochip/picochip.md (revision 162666) +++ gcc/config/picochip/picochip.md (working copy) @@ -665,7 +665,10 @@ rtx shiftVal; rtx loadedValue; rtx addressMask; + rtx topByteValue; + rtx signExtendedValue; + warn_of_byte_access(); /* Load the constant 1 into a register. */ @@ -713,11 +716,11 @@ emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress))); /* Shift the desired byte to the most significant byte. */ - rtx topByteValue = gen_reg_rtx (HImode); + topByteValue = gen_reg_rtx (HImode); emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal)); /* Sign extend the top-byte back into the bottom byte. */ - rtx signExtendedValue = gen_reg_rtx(HImode); + signExtendedValue = gen_reg_rtx(HImode); emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8))); /* Final extraction of QI mode register. */ @@ -729,8 +732,8 @@ { rtx zeroingByteMask; rtx temp; - rtx tempQiMode; rtx tempHiMode; + rtx lsbByteMask; /* Get the address. */ address = gen_reg_rtx(HImode); @@ -764,19 +767,10 @@ * bits, instead of the original memory value which is being * modified. */ - /*if (register_operand(operands[1],QImode)) - { - tempHiMode = XEXP(operands[1], 0); - } - else - { - tempHiMode = operands[1]; - }*/ - //tempHiMode = force_reg(QImode, operands[1]); tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0); temp = gen_reg_rtx(HImode); emit_insn(gen_rtx_SET(HImode, temp, tempHiMode)); - rtx lsbByteMask = gen_reg_rtx (HImode); + lsbByteMask = gen_reg_rtx (HImode); emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF))); emit_insn (gen_andhi3 (temp, temp, lsbByteMask)); @@ -913,6 +907,20 @@ // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0 STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1") +;; memcpy pattern +;; 0 = destination (mem:BLK ...) +;; 1 = source (mem:BLK ...) +;; 2 = count +;; 3 = alignment +(define_expand "movmemhi" + [(match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "") + (match_operand:HI 2 "immediate_operand" "") + (match_operand 3 "" "")] + "picochip_schedule_type != DFA_TYPE_NONE" + "if (picochip_expand_movmemhi(operands)) DONE; FAIL;" +) + ;;=========================================================================== ;; NOP ;;=========================================================================== @@ -1849,12 +1857,18 @@ { /* Synthesise a variable shift. */ + rtx tmp1; + rtx tmp2; + rtx tmp3; + rtx minus_one; + rtx tmp4; + /* Fill a temporary with the sign bits. */ - rtx tmp1 = gen_reg_rtx (HImode); + tmp1 = gen_reg_rtx (HImode); emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15))); /* Shift the unsigned value. */ - rtx tmp2 = gen_reg_rtx (HImode); + tmp2 = gen_reg_rtx (HImode); emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2])); /* The word of sign bits must be shifted back to the left, to zero @@ -1862,10 +1876,10 @@ * count). Since the shifts are computed modulo 16 (i.e., only the * lower 4 bits of the count are used), the shift amount (15 - count) * is equivalent to !count. */ - rtx tmp3 = gen_reg_rtx (HImode); - rtx tmp3_1 = GEN_INT (-1); - emit_insn (gen_xorhi3 (tmp3, operands[2], tmp3_1)); - rtx tmp4 = gen_reg_rtx (HImode); + tmp3 = gen_reg_rtx (HImode); + minus_one = GEN_INT (-1); + emit_insn (gen_xorhi3 (tmp3, operands[2], minus_one)); + tmp4 = gen_reg_rtx (HImode); emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3)); /* Combine the sign bits with the shifted value. */ @@ -2372,7 +2386,7 @@ UNSPEC_TESTPORT)) (clobber (reg:CC CC_REGNUM))] "" - "// %0 := TestPort(%1)\;COPY.1 0,%0 \\\ TSTPORT %1\;COPYEQ 1,%0" + "// %0 := TestPort(%1)\;COPY.1 0,%0 %| TSTPORT %1\;COPYEQ 1,%0" [(set_attr "length" "9")]) ; Entry point for array tstport (the actual port index is computed as the