+2015-12-15 Nathan Sidwell <nathan@acm.org>
+
+ * config/nvptx/nvptx.md (nvptx_register_operand): Don't accept and
+ then reject subregs.
+ (nvptx_reg_or_mem_operand): Likewise.
+ (nvptx_nonmemory_operand): Likewise.
+ (call_insn_operand): A regular predicate, check SYMBOL_REF_FUNCTION_P.
+ (call_insn, call_value_insn): Address is not SImode.
+ * config/nvptx/nvptx.h (FIXED_REGISTERS): Make return reg fixed.
+ (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Remove
+ RETURN_REG class.
+ (REGNO_REG_CLASS): Alwaus ALL_REGS.
+ (PROMOTE_MODE): QI and HI are the only smaller than SI int modes.
+ (HARD_FRAME_POINTER_REGNUM): Delete.
+ (REGISTER_NAMES): Move earlier.
+ (struct nvptx_args): Remove 'off'.
+ (INIT_CUMULATIVE_ARGS): Don't initialize 'off'.
+ (ELIMINABLE_REGS): Remove HARD_FRAME_POINTER_REGNUM.
+ * config/nvptx/nvptx.c (arg_promotion): Delete.
+ (nvptx_expand_call): Remove check for funtype being an fntype.
+
2015-12-15 Jason Merrill <jason@redhat.com>
* hash-map.h, hash-table.h: Make copy constructors explicit.
"omp declare target link" variables.
* omp-low.c (scan_sharing_clauses): Do not remove mapping of "omp
declare target link" variables.
- (add_decls_addresses_to_decl_constructor): For "omp declare target link"
- variables output address of the artificial pointer instead of address of
- the variable. Set most significant bit of the size to mark them.
+ (add_decls_addresses_to_decl_constructor): For "omp declare target
+ link" variables output address of the artificial pointer instead
+ of address of the variable. Set most significant bit of the size
+ to mark them.
(pass_data_omp_target_link): New pass_data.
(pass_omp_target_link): New class.
(find_link_var_op): New static function.
}
\f
-/* Perform a mode promotion for a function argument with MODE. Return
- the promoted mode. */
-
-static machine_mode
-arg_promotion (machine_mode mode)
-{
- if (mode == QImode || mode == HImode)
- return SImode;
- return mode;
-}
-
/* Determine whether MODE and TYPE (possibly NULL) should be passed or
returned in memory. Integer and floating types supported by the
machine are passed in registers, everything else is passed in
}
if (cfun->machine->funtype
- /* It's possible to construct testcases where we call a variable.
- See compile/20020129-1.c. stdarg_p will crash so avoid calling it
- in such a case. */
- && (TREE_CODE (cfun->machine->funtype) == FUNCTION_TYPE
- || TREE_CODE (cfun->machine->funtype) == METHOD_TYPE)
&& stdarg_p (cfun->machine->funtype))
{
varargs = gen_reg_rtx (Pmode);
hard registers for special purposes and leave pseudos unallocated. */
#define FIRST_PSEUDO_REGISTER 16
+/* We have to have some available hard registers, to keep gcc setup
+ happy. */
#define FIXED_REGISTERS \
- { 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }
+ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }
#define CALL_USED_REGISTERS \
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
enum reg_class
{
NO_REGS,
- RETURN_REG,
ALL_REGS,
LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
#define REG_CLASS_NAMES { \
- "RETURN_REG", \
"NO_REGS", \
"ALL_REGS" }
{ \
/* NO_REGS. */ \
{ 0x0000 }, \
- /* RETURN_REG. */ \
- { 0x0008 }, \
/* ALL_REGS. */ \
{ 0xFFFF }, \
}
#define GENERAL_REGS ALL_REGS
-#define REGNO_REG_CLASS(R) ((R) == 4 ? RETURN_REG : ALL_REGS)
+#define REGNO_REG_CLASS(R) ((void)(R), ALL_REGS)
#define BASE_REG_CLASS ALL_REGS
#define INDEX_REG_CLASS NO_REGS
#define MODES_TIEABLE_P(M1, M2) false
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
- if (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < GET_MODE_SIZE (SImode)) \
+ if ((MODE) == QImode || (MODE) == HImode) \
{ \
(MODE) = SImode; \
+ (void)(UNSIGNEDP); \
+ (void)(TYPE); \
}
/* Stack and Calling. */
#define STACK_GROWS_DOWNWARD 1
#define STACK_POINTER_REGNUM 1
-#define HARD_FRAME_POINTER_REGNUM 2
#define NVPTX_RETURN_REGNUM 4
#define FRAME_POINTER_REGNUM 15
#define ARG_POINTER_REGNUM 14
#define STATIC_CHAIN_REGNUM 12
#define OUTGOING_STATIC_CHAIN_REGNUM 10
+#define REGISTER_NAMES \
+ { \
+ "%hr0", "%outargs", "%hfp", "%hr3", "%retval", "%hr5", "%hr6", "%hr7", \
+ "%hr8", "%hr9", "%chain_out", "%hr11", "%chain_in", "%hr13", "%argp", "%frame" \
+ }
+
#define FIRST_PARM_OFFSET(FNDECL) ((void)(FNDECL), 0)
#define PUSH_ARGS_REVERSED 1
#define ACCUMULATE_OUTGOING_ARGS 1
tree fntype;
/* Number of arguments passed in registers so far. */
int count;
- /* Offset into the stdarg area so far. */
- HOST_WIDE_INT off;
};
#endif
#define CUMULATIVE_ARGS struct nvptx_args
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
- ((CUM).fntype = (FNTYPE), (CUM).count = 0, (CUM).off = 0, (void)0)
+ ((CUM).fntype = (FNTYPE), (CUM).count = 0, (void)0)
#define FUNCTION_ARG_REGNO_P(r) 0
expand_builtin_setjmp_receiver from generating invalid insns. */
#define ELIMINABLE_REGS \
{ \
- { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM} \
}
/* Define the offset between two registers, one to be eliminated, and the other
#undef ASM_APP_OFF
#define ASM_APP_OFF "\t// #NO_APP \n"
-#define REGISTER_NAMES \
- { \
- "%hr0", "%outargs", "%hfp", "%hr3", "%retval", "%hr5", "%hr6", "%hr7", \
- "%hr8", "%hr9", "%chain_out", "%hr11", "%chain_in", "%hr13", "%argp", "%frame" \
- }
-
#define DBX_REGISTER_NUMBER(N) N
#define TEXT_SECTION_ASM_OP ""
(const_string "false"))
(define_predicate "nvptx_register_operand"
- (match_code "reg,subreg")
+ (match_code "reg")
{
if (REG_P (op))
return !HARD_REGISTER_P (op);
- if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
- return false;
- if (GET_CODE (op) == SUBREG)
- return false;
return register_operand (op, mode);
})
(define_predicate "nvptx_reg_or_mem_operand"
- (match_code "mem,reg,subreg")
+ (match_code "mem,reg")
{
if (REG_P (op))
return !HARD_REGISTER_P (op);
- if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
- return false;
- if (GET_CODE (op) == SUBREG)
- return false;
return memory_operand (op, mode) || register_operand (op, mode);
})
;; Registers or constants for normal instructions. Does not allow symbolic
;; constants.
(define_predicate "nvptx_nonmemory_operand"
- (match_code "reg,subreg,const_int,const_double")
+ (match_code "reg,const_int,const_double")
{
if (REG_P (op))
return !HARD_REGISTER_P (op);
- if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
- return false;
- if (GET_CODE (op) == SUBREG)
- return false;
return nonmemory_operand (op, mode);
})
(match_code "eq,ne,le,ge,lt,gt,uneq,unle,unge,unlt,ungt,unordered,ordered"))
;; Test for a valid operand for a call instruction.
-(define_special_predicate "call_insn_operand"
+(define_predicate "call_insn_operand"
(match_code "symbol_ref,reg")
{
- if (GET_CODE (op) == SYMBOL_REF)
- {
- tree decl = SYMBOL_REF_DECL (op);
- /* This happens for libcalls. */
- if (decl == NULL_TREE)
- return true;
- return TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL;
- }
- return true;
+ return GET_CODE (op) != SYMBOL_REF || SYMBOL_REF_FUNCTION_P (op);
})
;; Return true if OP is a call with parallel USEs of the argument
(define_insn "call_insn"
[(match_parallel 2 "call_operation"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "Rs"))
+ [(call (mem:QI (match_operand 0 "call_insn_operand" "Rs"))
(match_operand 1))])]
""
{
(define_insn "call_value_insn"
[(match_parallel 3 "call_operation"
[(set (match_operand 0 "nvptx_register_operand" "=R")
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "Rs"))
+ (call (mem:QI (match_operand 1 "call_insn_operand" "Rs"))
(match_operand 2)))])]
""
{