constraints.md (U, v): New constraints.
2015-07-14 Sandra Loosemore <sandra@codesourcery.com> Cesar Philippidis <cesar@codesourcery.com> Chung-Lin Tang <cltang@codesourcery.com> gcc/ * config/nios2/constraints.md (U, v): New constraints. * config/nios2/predicates.md (rdprs_dcache_operand): New. (ldstex_memory_operand): New. * config/nios2/sync.md: New file. * config/nios2/nios2.md (unspecv): Add new builtin function UNSPECV codes. (rdprs, flushd, flushda, wrpie, eni): New patterns. (top-level): Include sync.md. * config/nios2/nios2.c (N2_FTYPES): Add function types for new builtins. (N2_BUILTINS): Add arch field setting, add new builtins. (enum nios2_builtin_code,nios2_builtins): Update N2_BUILTIN_DEF for arch field. (nios2_expand_ldst_builtin): Rename from nios2_expand_ldstio_builtin. Also handle ldex/stex/ldsex/stsex builtins. (nios2_expand_rdprs_builtin): New function. (nios2_expand_cache_builtin): New function. (nios2_expand_wrpie_builtin): New function. (nios2_expand_eni_builtin): New function. (nios2_expand_builtin): Add arch field handling and new builtin cases. * doc/extend.texi (Altera Nios II Built-in Functions): Document new builtins. * doc/md.texi (Machine Constraints): Document U and v constraints. gcc/testsuite/ * gcc.target/nios2/nios2-flushd.c: New. * gcc.target/nios2/nios2-rdprs.c: New. * gcc.target/nios2/r2-atomic.c: New. * gcc.target/nios2/r2-eni.c: New. * gcc.target/nios2/r2-wrpie.c: New. Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com> Co-Authored-By: Chung-Lin Tang <cltang@codesourcery.com> From-SVN: r225800
This commit is contained in:
parent
c3ff2812ae
commit
524d2e49f2
14 changed files with 429 additions and 21 deletions
|
@ -1,3 +1,32 @@
|
|||
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Cesar Philippidis <cesar@codesourcery.com>
|
||||
Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
* config/nios2/constraints.md (U, v): New constraints.
|
||||
* config/nios2/predicates.md (rdprs_dcache_operand): New.
|
||||
(ldstex_memory_operand): New.
|
||||
* config/nios2/sync.md: New file.
|
||||
* config/nios2/nios2.md (unspecv): Add new builtin function
|
||||
UNSPECV codes.
|
||||
(rdprs, flushd, flushda, wrpie, eni): New patterns.
|
||||
(top-level): Include sync.md.
|
||||
* config/nios2/nios2.c (N2_FTYPES): Add function types for
|
||||
new builtins.
|
||||
(N2_BUILTINS): Add arch field setting, add new builtins.
|
||||
(enum nios2_builtin_code,nios2_builtins): Update N2_BUILTIN_DEF
|
||||
for arch field.
|
||||
(nios2_expand_ldst_builtin): Rename from nios2_expand_ldstio_builtin.
|
||||
Also handle ldex/stex/ldsex/stsex builtins.
|
||||
(nios2_expand_rdprs_builtin): New function.
|
||||
(nios2_expand_cache_builtin): New function.
|
||||
(nios2_expand_wrpie_builtin): New function.
|
||||
(nios2_expand_eni_builtin): New function.
|
||||
(nios2_expand_builtin): Add arch field handling and new builtin
|
||||
cases.
|
||||
* doc/extend.texi (Altera Nios II Built-in Functions): Document
|
||||
new builtins.
|
||||
* doc/md.texi (Machine Constraints): Document U and v constraints.
|
||||
|
||||
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Cesar Philippidis <cesar@codesourcery.com>
|
||||
Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
;; M: 0
|
||||
;; N: 0 to 255 (for custom instruction numbers)
|
||||
;; O: 0 to 31 (for control register numbers)
|
||||
;; U: -32768 to 32767 under R1, -2048 to 2047 under R2
|
||||
;;
|
||||
;; We use the following constraint letters for memory constraints
|
||||
;;
|
||||
;; v: memory operands for R2 load/store exclusive instructions
|
||||
;; w: memory operands for load/store IO and cache instructions
|
||||
;;
|
||||
;; We use the following built-in register classes:
|
||||
|
@ -100,6 +102,17 @@
|
|||
"A constant unspec offset representing a relocation."
|
||||
(match_test "nios2_unspec_reloc_p (op)"))
|
||||
|
||||
(define_constraint "U"
|
||||
"A 12-bit or 16-bit constant (for RDPRS and DCACHE)."
|
||||
(and (match_code "const_int")
|
||||
(if_then_else (match_test "TARGET_ARCH_R2")
|
||||
(match_test "SMALL_INT12 (ival)")
|
||||
(match_test "SMALL_INT (ival)"))))
|
||||
|
||||
(define_memory_constraint "v"
|
||||
"A memory operand suitable for R2 load/store exclusive instructions."
|
||||
(match_operand 0 "ldstex_memory_operand"))
|
||||
|
||||
(define_memory_constraint "w"
|
||||
"A memory operand suitable for load/store IO and cache instructions."
|
||||
(match_operand 0 "ldstio_memory_operand"))
|
||||
|
|
|
@ -135,12 +135,16 @@ static bool custom_code_conflict = false;
|
|||
N2_FTYPE(2, (SI, SF)) \
|
||||
N2_FTYPE(3, (SI, SF, SF)) \
|
||||
N2_FTYPE(2, (SI, SI)) \
|
||||
N2_FTYPE(3, (SI, SI, SI)) \
|
||||
N2_FTYPE(3, (SI, VPTR, SI)) \
|
||||
N2_FTYPE(2, (UI, CVPTR)) \
|
||||
N2_FTYPE(2, (UI, DF)) \
|
||||
N2_FTYPE(2, (UI, SF)) \
|
||||
N2_FTYPE(2, (VOID, DF)) \
|
||||
N2_FTYPE(2, (VOID, SF)) \
|
||||
N2_FTYPE(2, (VOID, SI)) \
|
||||
N2_FTYPE(3, (VOID, SI, SI)) \
|
||||
N2_FTYPE(2, (VOID, VPTR)) \
|
||||
N2_FTYPE(3, (VOID, VPTR, SI))
|
||||
|
||||
#define N2_FTYPE_OP1(R) N2_FTYPE_ ## R ## _VOID
|
||||
|
@ -3266,33 +3270,43 @@ nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
|
|||
struct nios2_builtin_desc
|
||||
{
|
||||
enum insn_code icode;
|
||||
enum nios2_arch_type arch;
|
||||
enum nios2_ftcode ftype;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define N2_BUILTINS \
|
||||
N2_BUILTIN_DEF (sync, N2_FTYPE_VOID_VOID) \
|
||||
N2_BUILTIN_DEF (ldbio, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldhio, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldwio, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (stbio, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (sthio, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (stwio, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (rdctl, N2_FTYPE_SI_SI) \
|
||||
N2_BUILTIN_DEF (wrctl, N2_FTYPE_VOID_SI_SI)
|
||||
N2_BUILTIN_DEF (sync, R1, N2_FTYPE_VOID_VOID) \
|
||||
N2_BUILTIN_DEF (ldbio, R1, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldbuio, R1, N2_FTYPE_UI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldhio, R1, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldhuio, R1, N2_FTYPE_UI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldwio, R1, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (stbio, R1, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (sthio, R1, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (stwio, R1, N2_FTYPE_VOID_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (rdctl, R1, N2_FTYPE_SI_SI) \
|
||||
N2_BUILTIN_DEF (wrctl, R1, N2_FTYPE_VOID_SI_SI) \
|
||||
N2_BUILTIN_DEF (rdprs, R1, N2_FTYPE_SI_SI_SI) \
|
||||
N2_BUILTIN_DEF (flushd, R1, N2_FTYPE_VOID_VPTR) \
|
||||
N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR) \
|
||||
N2_BUILTIN_DEF (wrpie, R2, N2_FTYPE_SI_SI) \
|
||||
N2_BUILTIN_DEF (eni, R2, N2_FTYPE_VOID_SI) \
|
||||
N2_BUILTIN_DEF (ldex, R2, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (ldsex, R2, N2_FTYPE_SI_CVPTR) \
|
||||
N2_BUILTIN_DEF (stex, R2, N2_FTYPE_SI_VPTR_SI) \
|
||||
N2_BUILTIN_DEF (stsex, R2, N2_FTYPE_SI_VPTR_SI)
|
||||
|
||||
enum nios2_builtin_code {
|
||||
#define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
|
||||
#define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
|
||||
N2_BUILTINS
|
||||
#undef N2_BUILTIN_DEF
|
||||
NUM_FIXED_NIOS2_BUILTINS
|
||||
};
|
||||
|
||||
static const struct nios2_builtin_desc nios2_builtins[] = {
|
||||
#define N2_BUILTIN_DEF(name, ftype) \
|
||||
{ CODE_FOR_ ## name, ftype, "__builtin_" #name },
|
||||
#define N2_BUILTIN_DEF(name, arch, ftype) \
|
||||
{ CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
|
||||
N2_BUILTINS
|
||||
#undef N2_BUILTIN_DEF
|
||||
};
|
||||
|
@ -3373,10 +3387,11 @@ nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
|
|||
}
|
||||
}
|
||||
|
||||
/* Expand ldio/stio form load-store instruction builtins. */
|
||||
/* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
|
||||
instruction builtins. */
|
||||
static rtx
|
||||
nios2_expand_ldstio_builtin (tree exp, rtx target,
|
||||
const struct nios2_builtin_desc *d)
|
||||
nios2_expand_ldst_builtin (tree exp, rtx target,
|
||||
const struct nios2_builtin_desc *d)
|
||||
{
|
||||
bool has_target_p;
|
||||
rtx addr, mem, val;
|
||||
|
@ -3388,14 +3403,21 @@ nios2_expand_ldstio_builtin (tree exp, rtx target,
|
|||
|
||||
if (insn_data[d->icode].operand[0].allows_mem)
|
||||
{
|
||||
/* stxio. */
|
||||
/* stxio/stex/stsex. */
|
||||
val = expand_normal (CALL_EXPR_ARG (exp, 1));
|
||||
if (CONST_INT_P (val))
|
||||
val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
|
||||
val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
|
||||
create_output_operand (&ops[0], mem, mode);
|
||||
create_input_operand (&ops[1], val, mode);
|
||||
has_target_p = false;
|
||||
if (insn_data[d->icode].n_operands == 3)
|
||||
{
|
||||
/* stex/stsex status value, returned as result of function. */
|
||||
create_output_operand (&ops[2], target, mode);
|
||||
has_target_p = true;
|
||||
}
|
||||
else
|
||||
has_target_p = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3404,7 +3426,8 @@ nios2_expand_ldstio_builtin (tree exp, rtx target,
|
|||
create_input_operand (&ops[1], mem, mode);
|
||||
has_target_p = true;
|
||||
}
|
||||
return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
|
||||
return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
|
||||
has_target_p);
|
||||
}
|
||||
|
||||
/* Expand rdctl/wrctl builtins. */
|
||||
|
@ -3436,6 +3459,81 @@ nios2_expand_rdwrctl_builtin (tree exp, rtx target,
|
|||
return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
|
||||
}
|
||||
|
||||
static rtx
|
||||
nios2_expand_rdprs_builtin (tree exp, rtx target,
|
||||
const struct nios2_builtin_desc *d)
|
||||
{
|
||||
rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
|
||||
rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
|
||||
struct expand_operand ops[MAX_RECOG_OPERANDS];
|
||||
|
||||
if (!rdwrctl_operand (reg, VOIDmode))
|
||||
{
|
||||
error ("Register number must be in range 0-31 for %s",
|
||||
d->name);
|
||||
return gen_reg_rtx (SImode);
|
||||
}
|
||||
|
||||
if (!rdprs_dcache_operand (imm, VOIDmode))
|
||||
{
|
||||
error ("The immediate value must fit into a %d-bit integer for %s",
|
||||
(TARGET_ARCH_R2) ? 12 : 16, d->name);
|
||||
return gen_reg_rtx (SImode);
|
||||
}
|
||||
|
||||
create_output_operand (&ops[0], target, SImode);
|
||||
create_input_operand (&ops[1], reg, SImode);
|
||||
create_integer_operand (&ops[2], INTVAL (imm));
|
||||
|
||||
return nios2_expand_builtin_insn (d, 3, ops, true);
|
||||
}
|
||||
|
||||
static rtx
|
||||
nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
|
||||
const struct nios2_builtin_desc *d)
|
||||
{
|
||||
rtx mem, addr;
|
||||
struct expand_operand ops[MAX_RECOG_OPERANDS];
|
||||
|
||||
addr = expand_normal (CALL_EXPR_ARG (exp, 0));
|
||||
mem = gen_rtx_MEM (SImode, addr);
|
||||
|
||||
create_input_operand (&ops[0], mem, SImode);
|
||||
|
||||
return nios2_expand_builtin_insn (d, 1, ops, false);
|
||||
}
|
||||
|
||||
static rtx
|
||||
nios2_expand_wrpie_builtin (tree exp, rtx target,
|
||||
const struct nios2_builtin_desc *d)
|
||||
{
|
||||
rtx val;
|
||||
struct expand_operand ops[MAX_RECOG_OPERANDS];
|
||||
|
||||
val = expand_normal (CALL_EXPR_ARG (exp, 0));
|
||||
create_input_operand (&ops[1], val, SImode);
|
||||
create_output_operand (&ops[0], target, SImode);
|
||||
|
||||
return nios2_expand_builtin_insn (d, 2, ops, true);
|
||||
}
|
||||
|
||||
static rtx
|
||||
nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
|
||||
const struct nios2_builtin_desc *d)
|
||||
{
|
||||
rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
|
||||
struct expand_operand ops[MAX_RECOG_OPERANDS];
|
||||
|
||||
if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
|
||||
{
|
||||
error ("The ENI instruction operand must be either 0 or 1");
|
||||
return const0_rtx;
|
||||
}
|
||||
create_integer_operand (&ops[0], INTVAL (imm));
|
||||
|
||||
return nios2_expand_builtin_insn (d, 1, ops, false);
|
||||
}
|
||||
|
||||
/* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
|
||||
a built-in function, with result going to TARGET if that's convenient
|
||||
(and in mode MODE if that's convenient).
|
||||
|
@ -3454,6 +3552,14 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
|
|||
{
|
||||
const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
|
||||
|
||||
if (d->arch > nios2_arch_option)
|
||||
{
|
||||
error ("Builtin function %s requires Nios II R%d",
|
||||
d->name, (int) d->arch);
|
||||
/* Given it is invalid, just generate a normal call. */
|
||||
return expand_call (exp, target, ignore);
|
||||
}
|
||||
|
||||
switch (fcode)
|
||||
{
|
||||
case NIOS2_BUILTIN_sync:
|
||||
|
@ -3468,12 +3574,29 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
|
|||
case NIOS2_BUILTIN_stbio:
|
||||
case NIOS2_BUILTIN_sthio:
|
||||
case NIOS2_BUILTIN_stwio:
|
||||
return nios2_expand_ldstio_builtin (exp, target, d);
|
||||
case NIOS2_BUILTIN_ldex:
|
||||
case NIOS2_BUILTIN_ldsex:
|
||||
case NIOS2_BUILTIN_stex:
|
||||
case NIOS2_BUILTIN_stsex:
|
||||
return nios2_expand_ldst_builtin (exp, target, d);
|
||||
|
||||
case NIOS2_BUILTIN_rdctl:
|
||||
case NIOS2_BUILTIN_wrctl:
|
||||
return nios2_expand_rdwrctl_builtin (exp, target, d);
|
||||
|
||||
case NIOS2_BUILTIN_rdprs:
|
||||
return nios2_expand_rdprs_builtin (exp, target, d);
|
||||
|
||||
case NIOS2_BUILTIN_flushd:
|
||||
case NIOS2_BUILTIN_flushda:
|
||||
return nios2_expand_cache_builtin (exp, target, d);
|
||||
|
||||
case NIOS2_BUILTIN_wrpie:
|
||||
return nios2_expand_wrpie_builtin (exp, target, d);
|
||||
|
||||
case NIOS2_BUILTIN_eni:
|
||||
return nios2_expand_eni_builtin (exp, target, d);
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
|
|
@ -62,6 +62,15 @@
|
|||
UNSPECV_CUSTOM_XNXX
|
||||
UNSPECV_LDXIO
|
||||
UNSPECV_STXIO
|
||||
UNSPECV_RDPRS
|
||||
UNSPECV_FLUSHD
|
||||
UNSPECV_FLUSHDA
|
||||
UNSPECV_WRPIE
|
||||
UNSPECV_ENI
|
||||
UNSPECV_LDEX
|
||||
UNSPECV_LDSEX
|
||||
UNSPECV_STEX
|
||||
UNSPECV_STSEX
|
||||
])
|
||||
|
||||
(define_c_enum "unspec" [
|
||||
|
@ -1127,6 +1136,48 @@
|
|||
"wrctl\\tctl%0, %z1"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
(define_insn "rdprs"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
|
||||
(match_operand:SI 2 "arith_operand" "U")]
|
||||
UNSPECV_RDPRS))]
|
||||
""
|
||||
"rdprs\\t%0, %1, %2"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
;; Cache Instructions
|
||||
|
||||
(define_insn "flushd"
|
||||
[(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
|
||||
UNSPECV_FLUSHD)]
|
||||
""
|
||||
"flushd\\t%0"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
(define_insn "flushda"
|
||||
[(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
|
||||
UNSPECV_FLUSHDA)]
|
||||
""
|
||||
"flushda\\t%0"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
;; R2 Instructions
|
||||
|
||||
(define_insn "wrpie"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
|
||||
UNSPECV_WRPIE))]
|
||||
"TARGET_ARCH_R2"
|
||||
"wrpie\\t%0, %1"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
(define_insn "eni"
|
||||
[(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
|
||||
UNSPECV_ENI)]
|
||||
"TARGET_ARCH_R2"
|
||||
"eni\\t%0"
|
||||
[(set_attr "type" "control")])
|
||||
|
||||
;; Trap patterns
|
||||
(define_insn "trap"
|
||||
[(trap_if (const_int 1) (const_int 3))]
|
||||
|
@ -1172,6 +1223,10 @@
|
|||
emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Synchronization Primitives
|
||||
(include "sync.md")
|
||||
|
||||
;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
|
||||
(include "ldstwm.md")
|
||||
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
(and (match_code "const_int")
|
||||
(match_test "RDWRCTL_INT (INTVAL (op))")))
|
||||
|
||||
(define_predicate "rdprs_dcache_operand"
|
||||
(and (match_code "const_int")
|
||||
(if_then_else (match_test "TARGET_ARCH_R2")
|
||||
(match_test "SMALL_INT12 (INTVAL (op))")
|
||||
(match_test "SMALL_INT (INTVAL (op))"))))
|
||||
|
||||
(define_predicate "custom_insn_opcode"
|
||||
(and (match_code "const_int")
|
||||
(match_test "CUSTOM_INSN_OPCODE (INTVAL (op))")))
|
||||
|
@ -144,3 +150,10 @@
|
|||
}
|
||||
return memory_operand (op, mode);
|
||||
})
|
||||
|
||||
(define_predicate "ldstex_memory_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
/* ldex/ldsex/stex/stsex cannot handle memory addresses with offsets. */
|
||||
return GET_CODE (XEXP (op, 0)) == REG;
|
||||
})
|
||||
|
|
45
gcc/config/nios2/sync.md
Normal file
45
gcc/config/nios2/sync.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
;; Machine Description for Altera Nios II synchronization primitives.
|
||||
;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
|
||||
;; Contributed by Mentor Graphics, Inc.
|
||||
;;
|
||||
;; 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_int_iterator UNSPECV_LOAD_EXCLUSIVE [UNSPECV_LDEX UNSPECV_LDSEX])
|
||||
(define_int_attr load_exclusive [(UNSPECV_LDEX "ldex")
|
||||
(UNSPECV_LDSEX "ldsex")])
|
||||
(define_insn "<load_exclusive>"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "ldstex_memory_operand" "v")]
|
||||
UNSPECV_LOAD_EXCLUSIVE))]
|
||||
"TARGET_ARCH_R2"
|
||||
"<load_exclusive>\\t%0, %A1"
|
||||
[(set_attr "type" "ld")])
|
||||
|
||||
(define_int_iterator UNSPECV_STORE_EXCLUSIVE [UNSPECV_STEX UNSPECV_STSEX])
|
||||
(define_int_attr store_exclusive [(UNSPECV_STEX "stex")
|
||||
(UNSPECV_STSEX "stsex")])
|
||||
(define_insn "<store_exclusive>"
|
||||
[(set (match_operand:SI 2 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(const_int 0)] UNSPECV_STORE_EXCLUSIVE))
|
||||
(set (match_operand:SI 0 "ldstex_memory_operand" "=v")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "reg_or_0_operand" "rM")]
|
||||
UNSPECV_STORE_EXCLUSIVE))]
|
||||
"TARGET_ARCH_R2"
|
||||
"<store_exclusive>\\t%2, %z1, %A0"
|
||||
[(set_attr "type" "st")])
|
|
@ -11045,7 +11045,16 @@ void __builtin_sthio (volatile void *, int)
|
|||
void __builtin_stwio (volatile void *, int)
|
||||
void __builtin_sync (void)
|
||||
int __builtin_rdctl (int)
|
||||
int __builtin_rdprs (int, int)
|
||||
void __builtin_wrctl (int, int)
|
||||
void __builtin_flushd (volatile void *)
|
||||
void __builtin_flushda (volatile void *)
|
||||
int __builtin_wrpie (int);
|
||||
void __builtin_eni (int);
|
||||
int __builtin_ldex (volatile const void *)
|
||||
int __builtin_stex (volatile void *, int)
|
||||
int __builtin_ldsex (volatile const void *)
|
||||
int __builtin_stsex (volatile void *, int)
|
||||
@end example
|
||||
|
||||
The following built-in functions are always available. They
|
||||
|
|
|
@ -2999,6 +2999,14 @@ Matches immediates which are addresses in the small
|
|||
data section and therefore can be added to @code{gp}
|
||||
as a 16-bit immediate to re-create their 32-bit value.
|
||||
|
||||
@item U
|
||||
Matches constants suitable as an operand for the rdprs and
|
||||
cache instructions.
|
||||
|
||||
@item v
|
||||
A memory operand suitable for Nios II R2 load/store
|
||||
exclusive instructions.
|
||||
|
||||
@item w
|
||||
A memory operand suitable for load/store IO and cache
|
||||
instructions.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Cesar Philippidis <cesar@codesourcery.com>
|
||||
Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
* gcc.target/nios2/nios2-flushd.c: New.
|
||||
* gcc.target/nios2/nios2-rdprs.c: New.
|
||||
* gcc.target/nios2/r2-atomic.c: New.
|
||||
* gcc.target/nios2/r2-eni.c: New.
|
||||
* gcc.target/nios2/r2-wrpie.c: New.
|
||||
|
||||
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Cesar Philippidis <cesar@codesourcery.com>
|
||||
Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
|
22
gcc/testsuite/gcc.target/nios2/nios2-flushd.c
Normal file
22
gcc/testsuite/gcc.target/nios2/nios2-flushd.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do assemble } */
|
||||
/* { dg-options "-O" } */
|
||||
|
||||
void test_flushd (unsigned char* p1, unsigned char* p2)
|
||||
{
|
||||
__builtin_flushd (p1);
|
||||
__builtin_flushd (p2);
|
||||
__builtin_flushd (p2 + 1);
|
||||
__builtin_flushd (p2 + 2);
|
||||
__builtin_flushd (p2 + 2047);
|
||||
__builtin_flushd (p2 + 2048);
|
||||
}
|
||||
|
||||
void test_flushda (unsigned char* p1, unsigned char* p2)
|
||||
{
|
||||
__builtin_flushda (p1);
|
||||
__builtin_flushda (p2);
|
||||
__builtin_flushda (p2 + 1);
|
||||
__builtin_flushda (p2 + 2);
|
||||
__builtin_flushda (p2 + 2047);
|
||||
__builtin_flushda (p2 + 2048);
|
||||
}
|
8
gcc/testsuite/gcc.target/nios2/nios2-rdprs.c
Normal file
8
gcc/testsuite/gcc.target/nios2/nios2-rdprs.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-final { scan-assembler "rdprs" } } */
|
||||
|
||||
int x ()
|
||||
{
|
||||
__builtin_rdprs (3,934);
|
||||
return 0;
|
||||
}
|
49
gcc/testsuite/gcc.target/nios2/r2-atomic.c
Normal file
49
gcc/testsuite/gcc.target/nios2/r2-atomic.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* { dg-do assemble } */
|
||||
/* { dg-options "-O -march=r2" } */
|
||||
|
||||
int test_stex (unsigned char* p1, unsigned char* p2)
|
||||
{
|
||||
int a, b, c, d;
|
||||
a = __builtin_stex (p1, *p2);
|
||||
b = __builtin_stex (p2, 0);
|
||||
c = __builtin_stex (p2 + 1, 0x80);
|
||||
d = __builtin_stex (p2 + 2, 0x7f);
|
||||
|
||||
return a + b + c + d;
|
||||
}
|
||||
|
||||
int test_stsex (unsigned short* p1, unsigned short* p2)
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
a = __builtin_stsex (p1, *p2);
|
||||
b = __builtin_stsex (p2, 0);
|
||||
c = __builtin_stsex (p2 + 1, 0x8000);
|
||||
d = __builtin_stsex (p2 + 2, 0x7fff);
|
||||
|
||||
return a + b + c + d;
|
||||
}
|
||||
|
||||
int test_ldex (unsigned char* p1, unsigned char* p2)
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
a = __builtin_ldex (p1);
|
||||
b = __builtin_ldex (p2);
|
||||
c = __builtin_ldex (p2 + 1);
|
||||
d = __builtin_ldex (p2 + 2);
|
||||
|
||||
return a + b + c + d;
|
||||
}
|
||||
|
||||
int test_ldsex (unsigned char* p1, unsigned char* p2)
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
a = __builtin_ldsex (p1);
|
||||
b = __builtin_ldsex (p2);
|
||||
c = __builtin_ldsex (p2 + 1);
|
||||
d = __builtin_ldsex (p2 + 2);
|
||||
|
||||
return a + b + c + d;
|
||||
}
|
10
gcc/testsuite/gcc.target/nios2/r2-eni.c
Normal file
10
gcc/testsuite/gcc.target/nios2/r2-eni.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -march=r2" } */
|
||||
/* { dg-final { scan-assembler "eni" } } */
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
__builtin_eni (0);
|
||||
__builtin_eni (1);
|
||||
}
|
14
gcc/testsuite/gcc.target/nios2/r2-wrpie.c
Normal file
14
gcc/testsuite/gcc.target/nios2/r2-wrpie.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -march=r2" } */
|
||||
/* { dg-final { scan-assembler "wrpie" } } */
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
int b;
|
||||
|
||||
b = __builtin_wrpie (a);
|
||||
a = __builtin_wrpie (b);
|
||||
|
||||
return a + b;
|
||||
}
|
Loading…
Add table
Reference in a new issue