new file mode 100644
@@ -0,0 +1,55 @@
+;; Constant defintions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; Register numbers.
+(define_constants
+ [(R8_REGNUM 8)
+ (TA_REGNUM 15)
+ (FP_REGNUM 28)
+ (GP_REGNUM 29)
+ (LP_REGNUM 30)
+ (SP_REGNUM 31)
+ ])
+
+
+;; The unpec operation index.
+(define_c_enum "unspec_element" [
+ UNSPEC_STACK_PUSH_MULTIPLE
+ UNSPEC_STACK_POP_MULTIPLE
+ UNSPEC_STACK_V3PUSH
+ UNSPEC_STACK_V3POP
+ UNSPEC_FUNC_RETURN
+])
+
+
+;; The unspec_volatile operation index.
+(define_c_enum "unspec_volatile_element" [
+ UNSPEC_VOLATILE_ISYNC
+ UNSPEC_VOLATILE_ISB
+ UNSPEC_VOLATILE_MFSR
+ UNSPEC_VOLATILE_MFUSR
+ UNSPEC_VOLATILE_MTSR
+ UNSPEC_VOLATILE_MTUSR
+ UNSPEC_VOLATILE_SETGIE_EN
+ UNSPEC_VOLATILE_SETGIE_DIS
+])
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,260 @@
+;; Constraint definitions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+;; Check 16.8.7 Defining Machine-Specific Constraints for detail.
+
+;; NO contrains can be prefixed with: E F V X g i m n o p r s
+;; Machine-dependent integer: I J K L M N O P
+;; Machine-dependent floating: G H
+
+
+(define_register_constraint "w" "(TARGET_ISA_V3 || TARGET_ISA_V3M) ? LOW_REGS : NO_REGS"
+ "LOW register class $r0 ~ $r7 constraint for V3/V3M ISA")
+
+(define_register_constraint "l" "LOW_REGS"
+ "LOW register class $r0 ~ $r7")
+
+(define_register_constraint "d" "MIDDLE_REGS"
+ "MIDDLE register class $r0 ~ $r11, $r16 ~ $r19")
+
+(define_register_constraint "h" "HIGH_REGS"
+ "HIGH register class $r12 ~ $r14, $r20 ~ $r31")
+
+
+(define_register_constraint "t" "R15_TA_REG"
+ "Temporary Assist register $ta (i.e. $r15)")
+
+(define_register_constraint "k" "STACK_REG"
+ "Stack register $sp")
+
+
+(define_constraint "Iu03"
+ "Unsigned immediate 3-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 3) && ival >= 0")))
+
+(define_constraint "In03"
+ "Negative immediate 3-bit value in the range of -7 to 0"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (ival, -7, 0)")))
+
+(define_constraint "Iu04"
+ "Unsigned immediate 4-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 4) && ival >= 0")))
+
+(define_constraint "Is05"
+ "Signed immediate 5-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 4) && ival >= -(1 << 4)")))
+
+(define_constraint "Iu05"
+ "Unsigned immediate 5-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 5) && ival >= 0")))
+
+(define_constraint "In05"
+ "Negative immediate 5-bit value in the range of -31 to 0"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (ival, -31, 0)")))
+
+;; Ip05 is special and dedicated for v3 movpi45 instruction.
+;; movpi45 has imm5u field but the range is 16 ~ 47.
+(define_constraint "Ip05"
+ "Unsigned immediate 5-bit value for movpi45 instruction with range 16-47"
+ (and (match_code "const_int")
+ (match_test "ival < ((1 << 5) + 16)
+ && ival >= (0 + 16)
+ && (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
+
+(define_constraint "Iu06"
+ "Unsigned immediate 6-bit value constraint for addri36.sp instruction"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 6)
+ && ival >= 0
+ && (ival % 4 == 0)
+ && (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
+
+(define_constraint "Iu08"
+ "Unsigned immediate 8-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 8) && ival >= 0")))
+
+(define_constraint "Iu09"
+ "Unsigned immediate 9-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 9) && ival >= 0")))
+
+
+(define_constraint "Is10"
+ "Signed immediate 10-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 9) && ival >= -(1 << 9)")))
+
+(define_constraint "Is11"
+ "Signed immediate 11-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 10) && ival >= -(1 << 10)")))
+
+
+(define_constraint "Is15"
+ "Signed immediate 15-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 14) && ival >= -(1 << 14)")))
+
+(define_constraint "Iu15"
+ "Unsigned immediate 15-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 15) && ival >= 0")))
+
+
+;; Ic15 is special and dedicated for performance extension
+;; 'bclr' (single-bit-clear) instruction.
+;; It is used in andsi3 pattern and recognized for the immediate
+;; which is NOT in the range of imm15u but OK for 'bclr' instruction.
+;; (If the immediate value IS in the range of imm15u,
+;; we can directly use 'andi' instruction.)
+(define_constraint "Ic15"
+ "A constant which is not in the range of imm15u but ok for bclr instruction"
+ (and (match_code "const_int")
+ (match_test "(ival & 0xffff8000) && nds32_can_use_bclr_p (ival)")))
+
+;; Ie15 is special and dedicated for performance extension
+;; 'bset' (single-bit-set) instruction.
+;; It is used in iorsi3 pattern and recognized for the immediate
+;; which is NOT in the range of imm15u but OK for 'bset' instruction.
+;; (If the immediate value IS in the range of imm15u,
+;; we can directly use 'ori' instruction.)
+(define_constraint "Ie15"
+ "A constant which is not in the range of imm15u but ok for bset instruction"
+ (and (match_code "const_int")
+ (match_test "(ival & 0xffff8000) && nds32_can_use_bset_p (ival)")))
+
+;; It15 is special and dedicated for performance extension
+;; 'btgl' (single-bit-toggle) instruction.
+;; It is used in xorsi3 pattern and recognized for the immediate
+;; which is NOT in the range of imm15u but OK for 'btgl' instruction.
+;; (If the immediate value IS in the range of imm15u,
+;; we can directly use 'xori' instruction.)
+(define_constraint "It15"
+ "A constant which is not in the range of imm15u but ok for btgl instruction"
+ (and (match_code "const_int")
+ (match_test "(ival & 0xffff8000) && nds32_can_use_btgl_p (ival)")))
+
+
+;; Ii15 is special and dedicated for v3 isa
+;; 'bitci' (bit-clear-immediate) instruction.
+;; It is used in andsi3 pattern and recognized for the immediate whose
+;; (~ival) value is in the range of imm15u and OK for 'bitci' instruction.
+;; For example, 'andi $r0,$r0,0xfffffffc' can be presented
+; with 'bitci $r0,$r0,3'.
+(define_constraint "Ii15"
+ "A constant whose compliment value is in the range of imm15u
+ and ok for bitci instruction"
+ (and (match_code "const_int")
+ (match_test "nds32_can_use_bitci_p (ival)")))
+
+
+(define_constraint "Is16"
+ "Signed immediate 16-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 15) && ival >= -(1 << 15)")))
+
+(define_constraint "Is17"
+ "Signed immediate 17-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 16) && ival >= -(1 << 16)")))
+
+
+(define_constraint "Is19"
+ "Signed immediate 19-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 18) && ival >= -(1 << 18)")))
+
+
+(define_constraint "Is20"
+ "Signed immediate 20-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 19) && ival >= -(1 << 19)")))
+
+
+(define_constraint "Ispl"
+ "The immediate value that need to be split"
+ (and (match_code "const_int")
+ (match_test "(ival & 0xfff) != 0")))
+
+(define_constraint "Ihig"
+ "The immediate value that can be simply set high 20-bit"
+ (and (match_code "const_int")
+ (match_test "(ival != 0) && ((ival & 0xfff) == 0)")))
+
+
+(define_constraint "Izeb"
+ "The immediate value 0xff"
+ (and (match_code "const_int")
+ (match_test "(ival == 0xff)")))
+
+(define_constraint "Izeh"
+ "The immediate value 0xffff"
+ (and (match_code "const_int")
+ (match_test "(ival == 0xffff)")))
+
+(define_constraint "Ixls"
+ "The immediate value 0x01"
+ (and (match_code "const_int")
+ (match_test "TARGET_PERF_EXT && (ival == 0x1)")))
+
+(define_constraint "Ix11"
+ "The immediate value 0x7ff"
+ (and (match_code "const_int")
+ (match_test "TARGET_PERF_EXT && (ival == 0x7ff)")))
+
+(define_constraint "Ibms"
+ "The immediate value with power of 2"
+ (and (match_code "const_int")
+ (match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M)
+ && (IN_RANGE (exact_log2 (ival), 0, 7))")))
+
+(define_constraint "Ifex"
+ "The immediate value with power of 2 minus 1"
+ (and (match_code "const_int")
+ (match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M)
+ && (IN_RANGE (exact_log2 (ival + 1), 1, 8))")))
+
+
+(define_memory_constraint "U33"
+ "Memory constraint for 333 format"
+ (and (match_code "mem")
+ (match_test "nds32_mem_format (op) == ADDRESS_LO_REG_IMM3U")))
+
+(define_memory_constraint "U45"
+ "Memory constraint for 45 format"
+ (and (match_code "mem")
+ (match_test "(nds32_mem_format (op) == ADDRESS_REG)
+ && (GET_MODE (op) == SImode)")))
+
+(define_memory_constraint "U37"
+ "Memory constraint for 37 format"
+ (and (match_code "mem")
+ (match_test "(nds32_mem_format (op) == ADDRESS_SP_IMM7U
+ || nds32_mem_format (op) == ADDRESS_FP_IMM7U)
+ && (GET_MODE (op) == SImode)")))
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,55 @@
+;; Code and mode itertator and attribute definitions
+;; of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+;;----------------------------------------------------------------------------
+;; Mode iterators.
+;;----------------------------------------------------------------------------
+
+;; A list of integer modes that are up to one word long.
+(define_mode_iterator QIHISI [QI HI SI])
+
+;; A list of integer modes that are up to one half-word long.
+(define_mode_iterator QIHI [QI HI])
+
+;; A list of the modes that are up to double-word long.
+(define_mode_iterator DIDF [DI DF])
+
+
+;;----------------------------------------------------------------------------
+;; Mode attributes.
+;;----------------------------------------------------------------------------
+
+(define_mode_attr size [(QI "b") (HI "h") (SI "w")])
+
+(define_mode_attr byte [(QI "1") (HI "2") (SI "4")])
+
+
+;;----------------------------------------------------------------------------
+;; Code iterators.
+;;----------------------------------------------------------------------------
+
+
+;;----------------------------------------------------------------------------
+;; Code attributes.
+;;----------------------------------------------------------------------------
+
+
+;;----------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,245 @@
+;; DImode/DFmode patterns description of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; -------------------------------------------------------------
+;; Move DImode/DFmode instructions.
+;; -------------------------------------------------------------
+
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+{
+ /* Need to force register if mem <- !reg. */
+ if (GET_CODE (operands[0]) == MEM && !REG_P (operands[1]))
+ operands[1] = force_reg (DImode, operands[1]);
+})
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+{
+ /* Need to force register if mem <- !reg. */
+ if (GET_CODE (operands[0]) == MEM && !REG_P (operands[1]))
+ operands[1] = force_reg (DFmode, operands[1]);
+})
+
+
+(define_insn "move_<mode>"
+ [(set (match_operand:DIDF 0 "nonimmediate_operand" "=r, r, r, m")
+ (match_operand:DIDF 1 "general_operand" " r, i, m, r"))]
+ ""
+{
+ rtx addr;
+ rtx otherops[5];
+
+ switch (which_alternative)
+ {
+ case 0:
+ return "movd44\t%0, %1";
+
+ case 1:
+ /* reg <- const_int, we ask gcc to split instruction. */
+ return "#";
+
+ case 2:
+ /* Refer to nds32_legitimate_address_p() in nds32.c,
+ we only allow "reg", "symbol_ref", "const", and "reg + const_int"
+ as address rtx for DImode/DFmode memory access. */
+ addr = XEXP (operands[1], 0);
+
+ otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+ otherops[2] = addr;
+
+ if (REG_P (addr))
+ {
+ /* (reg) <- (mem (reg)) */
+ output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops);
+ }
+ else if (GET_CODE (addr) == PLUS)
+ {
+ /* (reg) <- (mem (plus (reg) (const_int))) */
+ rtx op0 = XEXP (addr, 0);
+ rtx op1 = XEXP (addr, 1);
+
+ if (REG_P (op0))
+ {
+ otherops[2] = op0;
+ otherops[3] = op1;
+ otherops[4] = gen_int_mode (INTVAL (op1) + 4, SImode);
+ }
+ else
+ {
+ otherops[2] = op1;
+ otherops[3] = op0;
+ otherops[4] = gen_int_mode (INTVAL (op0) + 4, SImode);
+ }
+
+ /* To avoid base overwrite when REGNO(%0) == REGNO(%2). */
+ if (REGNO (otherops[0]) != REGNO (otherops[2]))
+ {
+ output_asm_insn ("lwi\t%0, [%2 + (%3)]", otherops);
+ output_asm_insn ("lwi\t%1, [%2 + (%4)]", otherops);
+ }
+ else
+ {
+ output_asm_insn ("lwi\t%1, [%2 + (%4)]", otherops);
+ output_asm_insn ("lwi\t%0,[ %2 + (%3)]", otherops);
+ }
+ }
+ else
+ {
+ /* (reg) <- (mem (symbol_ref ...))
+ (reg) <- (mem (const ...)) */
+ output_asm_insn ("lwi.gp\t%0, [ + %2]", otherops);
+ output_asm_insn ("lwi.gp\t%1, [ + %2 + 4]", otherops);
+ }
+
+ /* We have already used output_asm_insn() by ourself,
+ so return an empty string. */
+ return "";
+
+ case 3:
+ /* Refer to nds32_legitimate_address_p() in nds32.c,
+ we only allow "reg", "symbol_ref", "const", and "reg + const_int"
+ as address rtx for DImode/DFmode memory access. */
+ addr = XEXP (operands[0], 0);
+
+ otherops[0] = gen_rtx_REG (SImode, REGNO (operands[1]));
+ otherops[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
+ otherops[2] = addr;
+
+ if (REG_P (addr))
+ {
+ /* (mem (reg)) <- (reg) */
+ output_asm_insn ("smw.bi\t%0, [%2], %1, 0", otherops);
+ }
+ else if (GET_CODE (addr) == PLUS)
+ {
+ /* (mem (plus (reg) (const_int))) <- (reg) */
+ rtx op0 = XEXP (addr, 0);
+ rtx op1 = XEXP (addr, 1);
+
+ if (REG_P (op0))
+ {
+ otherops[2] = op0;
+ otherops[3] = op1;
+ otherops[4] = gen_int_mode (INTVAL (op1) + 4, SImode);
+ }
+ else
+ {
+ otherops[2] = op1;
+ otherops[3] = op0;
+ otherops[4] = gen_int_mode (INTVAL (op0) + 4, SImode);
+ }
+
+ /* To avoid base overwrite when REGNO(%0) == REGNO(%2). */
+ if (REGNO (otherops[0]) != REGNO (otherops[2]))
+ {
+ output_asm_insn ("swi\t%0, [%2 + (%3)]", otherops);
+ output_asm_insn ("swi\t%1, [%2 + (%4)]", otherops);
+ }
+ else
+ {
+ output_asm_insn ("swi\t%1, [%2 + (%4)]", otherops);
+ output_asm_insn ("swi\t%0, [%2 + (%3)]", otherops);
+ }
+ }
+ else
+ {
+ /* (mem (symbol_ref ...)) <- (reg)
+ (mem (const ...)) <- (reg) */
+ output_asm_insn ("swi.gp\t%0, [ + %2]", otherops);
+ output_asm_insn ("swi.gp\t%1, [ + %2 + 4]", otherops);
+ }
+
+ /* We have already used output_asm_insn() by ourself,
+ so return an empty string. */
+ return "";
+
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "move,move,move,move")
+ (set_attr "length" " 4, 16, 8, 8")])
+
+(define_split
+ [(set (match_operand:DIDF 0 "register_operand" "")
+ (match_operand:DIDF 1 "const_double_operand" ""))]
+ "reload_completed"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 5))]
+{
+ /* Construct lowpart rtx. */
+ operands[2] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_lowpart (SImode, operands[1]);
+
+ /* Construct highpart rtx. */
+ /* Note that operands[1] can be VOIDmode constant,
+ so we need to use gen_highpart_mode().
+ Refer to gcc/emit-rtl.c for more information. */
+ operands[4] = gen_highpart (SImode, operands[0]);
+ operands[5] = gen_highpart_mode (SImode,
+ GET_MODE (operands[0]), operands[1]);
+})
+
+;; There is 'movd44' instruction for DImode/DFmode movement under V3/V3M ISA.
+;; We only need to split it under V2 ISA or none-16-bit code generation.
+(define_split
+ [(set (match_operand:DIDF 0 "register_operand" "")
+ (match_operand:DIDF 1 "register_operand" ""))]
+ "reload_completed
+ && (TARGET_ISA_V2 || !TARGET_16_BIT)"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (match_dup 3))]
+{
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[1]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+
+ /* Handle a partial overlap. */
+ if (rtx_equal_p (operands[0], operands[3]))
+ {
+ rtx tmp0 = operands[0];
+ rtx tmp1 = operands[1];
+
+ operands[0] = operands[2];
+ operands[1] = operands[3];
+ operands[2] = tmp0;
+ operands[3] = tmp1;
+ }
+})
+
+;; -------------------------------------------------------------
+;; Boolean DImode instructions.
+;; -------------------------------------------------------------
+
+;; Nowadays, the generic code is supposed to split the DImode
+;; boolean operations and have good code generation.
+;; Unless we find out some bad cases, there is no need to
+;; define DImode boolean operations by ourself.
+
+;; -------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,97 @@
+;; Intrinsic patterns description of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+;; ------------------------------------------------------------------------
+
+;; Register Transfer.
+
+(define_insn "unspec_volatile_mfsr"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFSR))]
+ ""
+ "mfsr\t%0, %V1"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_volatile_mfusr"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFUSR))]
+ ""
+ "mfusr\t%0, %V1"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_volatile_mtsr"
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)]
+ ""
+ "mtsr\t%0, %V1"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_volatile_mtusr"
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTUSR)]
+ ""
+ "mtusr\t%0, %V1"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
+;; ------------------------------------------------------------------------
+
+;; Interrupt Instructions.
+
+(define_insn "unspec_volatile_setgie_en"
+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_EN)]
+ ""
+ "setgie.e"
+ [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_volatile_setgie_dis"
+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_DIS)]
+ ""
+ "setgie.d"
+ [(set_attr "type" "misc")]
+)
+
+;; ------------------------------------------------------------------------
+
+;; Cache Synchronization Instructions
+
+(define_insn "unspec_volatile_isync"
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_ISYNC)]
+ ""
+ "isync\t%0"
+ [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_volatile_isb"
+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_ISB)]
+ ""
+ "isb"
+ [(set_attr "type" "misc")]
+)
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,21 @@
+/* Extra machine modes of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+/* So far, there is no need to define any modes for nds32 target. */
new file mode 100644
@@ -0,0 +1,410 @@
+;; Load/Store Multiple patterns description of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.for NDS32.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; Load Multiple Insns.
+;;
+;; operands[0] is the first of the consecutive registers.
+;; operands[1] is the first memory location.
+;; operands[2] is the number of consecutive registers.
+
+(define_expand "load_multiple"
+ [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
+ (match_operand:SI 1 "" ""))
+ (use (match_operand:SI 2 "" ""))])]
+ ""
+{
+ int maximum;
+
+ /* Because reduced-set regsiters has few registers
+ (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot
+ be used for register allocation),
+ using 8 registers for load_multiple may easily consume all of them.
+ It makes register allocation/spilling hard to work.
+ So we only allow maximum=4 registers for load_multiple
+ under reduced-set registers. */
+ if (TARGET_REDUCED_REGS)
+ maximum = 4;
+ else
+ maximum = 8;
+
+ /* Here are the conditions that must be all passed,
+ otherwise we have to FAIL this rtx generation:
+ 1. The number of consecutive registers must be integer.
+ 2. Maximum 4 or 8 registers for lmw.bi instruction
+ (based on this nds32-multiple.md design).
+ 3. Minimum 2 registers for lmw.bi instruction
+ (based on this nds32-multiple.md design).
+ 4. operands[0] must be register for sure.
+ 5. operands[1] must be memory for sure.
+ 6. Do not cross $r15 register because it is not allocatable. */
+ if (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) > maximum
+ || INTVAL (operands[2]) < 2
+ || GET_CODE (operands[0]) != REG
+ || GET_CODE (operands[1]) != MEM
+ || REGNO (operands[0]) + INTVAL (operands[2]) > TA_REGNUM)
+ FAIL;
+
+ /* For (mem addr), we force_reg on addr here,
+ so that nds32_expand_load_multiple can easily use it. */
+ operands[3] = nds32_expand_load_multiple (REGNO (operands[0]),
+ INTVAL (operands[2]),
+ force_reg (SImode,
+ XEXP (operands[1], 0)),
+ operands[1]);
+})
+
+;; Ordinary Load Multiple.
+
+(define_insn "*lmwsi8"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+ (set (match_operand:SI 8 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 24))))
+ (set (match_operand:SI 9 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
+ "(XVECLEN (operands[0], 0) == 8)"
+ "lmw.bi\t%2, [%1], %9, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi7"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+ (set (match_operand:SI 8 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
+ "(XVECLEN (operands[0], 0) == 7)"
+ "lmw.bi\t%2, [%1], %8, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi6"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
+ "(XVECLEN (operands[0], 0) == 6)"
+ "lmw.bi\t%2, [%1], %7, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi5"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
+ "(XVECLEN (operands[0], 0) == 5)"
+ "lmw.bi\t%2, [%1], %6, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi4"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
+ "(XVECLEN (operands[0], 0) == 4)"
+ "lmw.bi\t%2, [%1], %5, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi3"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
+ "(XVECLEN (operands[0], 0) == 3)"
+ "lmw.bi\t%2, [%1], %4, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*lmwsi2"
+ [(match_parallel 0 "nds32_load_multiple_operation"
+ [(set (match_operand:SI 2 "register_operand" "")
+ (mem:SI (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
+ "(XVECLEN (operands[0], 0) == 2)"
+ "lmw.bi\t%2, [%1], %3, 0x0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+
+;; Store Multiple Insns.
+;;
+;; operands[0] is the first memory location.
+;; opernads[1] is the first of the consecutive registers.
+;; operands[2] is the number of consecutive registers.
+
+(define_expand "store_multiple"
+ [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
+ (match_operand:SI 1 "" ""))
+ (use (match_operand:SI 2 "" ""))])]
+ ""
+{
+ int maximum;
+
+ /* Because reduced-set regsiters has few registers
+ (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot
+ be used for register allocation),
+ using 8 registers for store_multiple may easily consume all of them.
+ It makes register allocation/spilling hard to work.
+ So we only allow maximum=4 registers for store_multiple
+ under reduced-set registers. */
+ if (TARGET_REDUCED_REGS)
+ maximum = 4;
+ else
+ maximum = 8;
+
+ /* Here are the conditions that must be all passed,
+ otherwise we have to FAIL this rtx generation:
+ 1. The number of consecutive registers must be integer.
+ 2. Maximum 4 or 8 registers for smw.bi instruction
+ (based on this nds32-multiple.md design).
+ 3. Minimum 2 registers for smw.bi instruction
+ (based on this nds32-multiple.md design).
+ 4. operands[0] must be memory for sure.
+ 5. operands[1] must be register for sure.
+ 6. Do not cross $r15 register because it is not allocatable. */
+ if (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) > maximum
+ || INTVAL (operands[2]) < 2
+ || GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != REG
+ || REGNO (operands[1]) + INTVAL (operands[2]) > TA_REGNUM)
+ FAIL;
+
+ /* For (mem addr), we force_reg on addr here,
+ so that nds32_expand_store_multiple can easily use it. */
+ operands[3] = nds32_expand_store_multiple (REGNO (operands[1]),
+ INTVAL (operands[2]),
+ force_reg (SImode,
+ XEXP (operands[0], 0)),
+ operands[0]);
+})
+
+;; Ordinary Store Multiple.
+
+(define_insn "*stmsi8"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 5 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 6 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 7 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 8 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
+ (match_operand:SI 9 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 8)"
+ "smw.bi\t%2, [%1], %9, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi7"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 5 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 6 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 7 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 8 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 7)"
+ "smw.bi\t%2, [%1], %8, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi6"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 5 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 6 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 7 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 6)"
+ "smw.bi\t%2, [%1], %7, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi5"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 5 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 6 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 5)"
+ "smw.bi\t%2, [%1], %6, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi4"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 5 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 4)"
+ "smw.bi\t%2, [%1], %5, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi3"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 4 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 3)"
+ "smw.bi\t%2, [%1], %4, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*stmsi2"
+ [(match_parallel 0 "nds32_store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:SI 2 "register_operand" ""))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 3 "register_operand" ""))])]
+ "(XVECLEN (operands[0], 0) == 2)"
+ "smw.bi\t%2, [%1], %3, 0x0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+;; Move a block of memory if it is word aligned and MORE than 2 words long.
+;; We could let this apply for blocks of less than this, but it clobbers so
+;; many registers that there is then probably a better way.
+;;
+;; operands[0] is the destination block of memory.
+;; operands[1] is the source block of memory.
+;; operands[2] is the number of bytes to move.
+;; operands[3] is the known shared alignment.
+
+(define_expand "movmemqi"
+ [(match_operand:BLK 0 "general_operand" "")
+ (match_operand:BLK 1 "general_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")]
+ ""
+{
+ if (nds32_expand_movmemqi (operands[0],
+ operands[1],
+ operands[2],
+ operands[3]))
+ DONE;
+
+ FAIL;
+})
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,35 @@
+/* Definitions for option handling of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef NDS32_OPTS_H
+#define NDS32_OPTS_H
+
+#define NDS32_DEFAULT_CACHE_BLOCK_SIZE 16
+#define NDS32_DEFAULT_ISR_VECTOR_SIZE (TARGET_ISA_V3 ? 4 : 16)
+
+/* The various ANDES ISA. */
+enum nds32_arch_type
+{
+ ARCH_V2,
+ ARCH_V3,
+ ARCH_V3M
+};
+
+#endif
new file mode 100644
@@ -0,0 +1,25 @@
+;; define_peephole2 optimization patterns of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; Use define_peephole and define_peephole2 to handle possible
+;; target-specific optimization in this file.
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,119 @@
+/* Prototypes for exported functions of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+
+/* ------------------------------------------------------------------------ */
+
+/* Defining Data Structures for Per-function Information. */
+
+extern void nds32_init_expanders (void);
+
+
+/* Register Usage. */
+
+/* -- How Values Fit in Registers. */
+
+extern int nds32_hard_regno_nregs (int, enum machine_mode);
+extern int nds32_hard_regno_mode_ok (int, enum machine_mode);
+
+
+/* Register Classes. */
+
+extern enum reg_class nds32_regno_reg_class (int);
+
+
+/* Stack Layout and Calling Conventions. */
+
+/* -- Basic Stack Layout. */
+
+extern rtx nds32_return_addr_rtx (int, rtx);
+
+/* -- Eliminating Frame Pointer and Arg Pointer. */
+
+extern HOST_WIDE_INT nds32_initial_elimination_offset (unsigned int,
+ unsigned int);
+
+/* -- Passing Arguments in Registers. */
+
+extern void nds32_init_cumulative_args (CUMULATIVE_ARGS *,
+ tree, rtx, tree, int);
+
+/* -- Function Entry and Exit. */
+
+extern void nds32_expand_prologue (void);
+extern void nds32_expand_epilogue (void);
+extern void nds32_expand_prologue_v3push (void);
+extern void nds32_expand_epilogue_v3pop (void);
+
+/* ------------------------------------------------------------------------ */
+
+/* Auxiliary functions for auxiliary macros in nds32.h. */
+
+extern bool nds32_ls_333_p (rtx, rtx, rtx, enum machine_mode);
+
+/* Auxiliary functions for expanding rtl used in nds32-multiple.md. */
+
+extern rtx nds32_expand_load_multiple (int, int, rtx, rtx);
+extern rtx nds32_expand_store_multiple (int, int, rtx, rtx);
+extern int nds32_expand_movmemqi (rtx, rtx, rtx, rtx);
+
+/* Auxiliary functions for multiple load/store predicate checking. */
+
+extern bool nds32_valid_multiple_load_store (rtx, bool);
+
+/* Auxiliary functions for bit operation detection. */
+
+extern int nds32_can_use_bclr_p (int);
+extern int nds32_can_use_bset_p (int);
+extern int nds32_can_use_btgl_p (int);
+
+extern int nds32_can_use_bitci_p (int);
+
+/* Auxiliary function for 'Computing the Length of an Insn'. */
+
+extern int nds32_adjust_insn_length (rtx, int);
+
+/* Auxiliary functions for FP_AS_GP detection. */
+
+extern bool nds32_symbol_load_store_p (rtx);
+extern int nds32_fp_as_gp_check_available (void);
+
+/* Auxiliary functions for jump table generation. */
+
+extern const char *nds32_output_casesi_pc_relative (rtx *);
+extern const char *nds32_output_casesi (rtx *);
+
+/* Auxiliary functions to identify 16 bit addresing mode. */
+
+extern enum nds32_16bit_address_type nds32_mem_format (rtx);
+
+/* Auxiliary functions to output assembly code. */
+
+extern const char *nds32_output_16bit_store (rtx *, int);
+extern const char *nds32_output_16bit_load (rtx *, int);
+extern const char *nds32_output_32bit_store (rtx *, int);
+extern const char *nds32_output_32bit_load (rtx *, int);
+extern const char *nds32_output_32bit_load_s (rtx *, int);
+
+/* Auxiliary functions to decide output alignment or not. */
+
+extern int nds32_target_alignment (rtx);
+
+/* ------------------------------------------------------------------------ */
new file mode 100644
@@ -0,0 +1,102 @@
+; Options of Andes NDS32 cpu for GNU compiler
+; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+; Contributed by Andes Technology Corporation.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published
+; by the Free Software Foundation; either version 3, or (at your
+; option) any later version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT
+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+; License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3. If not see
+; <http://www.gnu.org/licenses/>.
+
+HeaderInclude
+config/nds32/nds32-opts.h
+
+mbig-endian
+Target Report RejectNegative Negative(mlittle-endian) Mask(BIG_ENDIAN)
+Generate code in big-endian mode.
+
+mlittle-endian
+Target Report RejectNegative Negative(mbig-endian) InverseMask(BIG_ENDIAN)
+Generate code in little-endian mode.
+
+mreduced-regs
+Target Report RejectNegative Negative(mfull-regs) Mask(REDUCED_REGS)
+Use reduced-set registers for register allocation.
+
+mfull-regs
+Target Report RejectNegative Negative(mreduced-regs) InverseMask(REDUCED_REGS)
+Use full-set registers for register allocation.
+
+mcmov
+Target Report Mask(CMOV)
+Generate conditional move instructions.
+
+mperf-ext
+Target Report Mask(PERF_EXT)
+Generate performance extension instructions.
+
+mv3push
+Target Report Mask(V3PUSH)
+Generate v3 push25/pop25 instructions.
+
+m16-bit
+Target Report Mask(16_BIT)
+Generate 16-bit instructions.
+
+mgp-direct
+Target Report Mask(GP_DIRECT)
+Generate GP base instructions directly.
+
+misr-vector-size=
+Target Report RejectNegative Joined UInteger Var(nds32_isr_vector_size) Init(NDS32_DEFAULT_ISR_VECTOR_SIZE)
+Specify the size of each interrupt vector, which must be 4 or 16.
+
+mcache-block-size=
+Target Report RejectNegative Joined UInteger Var(nds32_cache_block_size) Init(NDS32_DEFAULT_CACHE_BLOCK_SIZE)
+Specify the size of each cache block, which must be a power of 2 between 4 and 512.
+
+march=
+Target RejectNegative Joined Enum(nds32_arch_type) Var(nds32_arch_option) Init(ARCH_V3)
+Specify the name of the target architecture.
+
+Enum
+Name(nds32_arch_type) Type(enum nds32_arch_type)
+
+EnumValue
+Enum(nds32_arch_type) String(v2) Value(ARCH_V2)
+
+EnumValue
+Enum(nds32_arch_type) String(v3) Value(ARCH_V3)
+
+EnumValue
+Enum(nds32_arch_type) String(v3m) Value(ARCH_V3M)
+
+mforce-fp-as-gp
+Target Report Mask(FORCE_FP_AS_GP)
+Prevent $fp being allocated during register allocation so that compiler is able to force performing fp-as-gp optimization.
+
+mforbid-fp-as-gp
+Target Report Mask(FORBID_FP_AS_GP)
+Forbid using $fp to access static and global variables. This option strictly forbids fp-as-gp optimization regardless of '-mforce-fp-as-gp'.
+
+mex9
+Target Report Mask(EX9)
+Use special directives to guide linker doing ex9 optimization.
+
+mctor-dtor
+Target Report
+Enable constructor/destructor feature.
+
+mrelax
+Target Report
+Guide linker to relax instructions.
new file mode 100644
@@ -0,0 +1,37 @@
+/* Intrinsic definitions of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _NDS32_INTRINSIC_H
+#define _NDS32_INTRINSIC_H
+
+enum nds32_intrinsic_registers
+{
+ __NDS32_REG_PSW__ = 1024,
+ __NDS32_REG_IPSW__,
+ __NDS32_REG_ITYPE__,
+ __NDS32_REG_IPC__
+};
+
+#endif /* nds32_intrinsic.h */
new file mode 100644
@@ -0,0 +1,29 @@
+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_automaton "nds32_machine")
+
+(define_cpu_unit "general_unit" "nds32_machine")
+
+(define_insn_reservation "simple_insn" 1
+ (eq_attr "type" "unknown,load,store,move,alu,compare,branch,call,misc")
+ "general_unit")
+
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,65 @@
+;; Predicate definitions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_predicate "nds32_equality_comparison_operator"
+ (match_code "eq,ne"))
+
+(define_predicate "nds32_greater_less_comparison_operator"
+ (match_code "gt,ge,lt,le"))
+
+(define_special_predicate "nds32_logical_binary_operator"
+ (match_code "and,ior,xor"))
+
+(define_predicate "nds32_symbolic_operand"
+ (match_code "const,symbol_ref,label_ref"))
+
+(define_predicate "nds32_nonsymbolic_operand"
+ (and (match_operand 0 "general_operand")
+ (not (match_code "high,const,symbol_ref,label_ref"))))
+
+(define_predicate "nds32_reg_constant_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_int_operand")))
+
+(define_predicate "nds32_rimm15s_operand"
+ (ior (match_operand 0 "register_operand")
+ (and (match_operand 0 "const_int_operand")
+ (match_test "satisfies_constraint_Is15 (op)"))))
+
+(define_predicate "nds32_imm5u_operand"
+ (and (match_operand 0 "const_int_operand")
+ (match_test "satisfies_constraint_Iu05 (op)")))
+
+(define_special_predicate "nds32_load_multiple_operation"
+ (match_code "parallel")
+{
+ /* To verify 'load' operation, pass 'true' for the second argument.
+ See the implementation in nds32.c for details. */
+ return nds32_valid_multiple_load_store (op, true);
+})
+
+(define_special_predicate "nds32_store_multiple_operation"
+ (match_code "parallel")
+{
+ /* To verify 'store' operation, pass 'false' for the second argument.
+ See the implementation in nds32.c for details. */
+ return nds32_valid_multiple_load_store (op, false);
+})
+;; ------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,30 @@
+# The multilib settings of Andes NDS32 cpu for GNU compiler
+# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+# Contributed by Andes Technology Corporation.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published
+# by the Free Software Foundation; either version 3, or (at your
+# option) any later version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# We need to build following multilibs:
+# -mlittle-endian
+# -mbig-endian
+#
+# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the
+# driver program which options are defaults for this target and thus
+# do not need to be handled specially.
+MULTILIB_OPTIONS = mlittle-endian/mbig-endian mgp-direct/mno-gp-direct
+
+# ------------------------------------------------------------------------