Skip to content

Commit 8679625

Browse files
author
Claudiu Zissulescu
committed
Allow anonymous arguments to be passed partly in registers (only ABI-HS)
1 parent e95e6ed commit 8679625

File tree

7 files changed

+117
-8
lines changed

7 files changed

+117
-8
lines changed

gcc/ChangeLog.ARC

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2013-07-29 Claudiu Zissulescu <[email protected]>
2+
3+
* config/arc/arc.c (arc_setup_incoming_varargs): Pass
4+
anonymous arguments in registers (ABI HS).
5+
(arc_function_args_impl): Likewise.
6+
* config/arc/arc.h (CUMULATIVE_ARGS.last_reg): New member.
7+
* testsuite/gcc.target/arc/abitest.S: New file.
8+
* testsuite/gcc.target/arc/va_args-1.c: Likewise.
9+
* testsuite/gcc.target/arc/va_args-2.c: Likewise.
10+
* testsuite/gcc.target/arc/va_args-3.c: Likewise.
11+
112
2013-07-23 Claudiu Zissulescu <[email protected]>
213

314
* config/arc/arc-opts.h (arc_abi_type): Define.

gcc/config/arc/arc.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,17 +1862,11 @@ arc_setup_incoming_varargs (cumulative_args_t args_so_far,
18621862
int first_anon_arg;
18631863
CUMULATIVE_ARGS next_cum;
18641864

1865-
if (TARGET_HS)
1866-
{
1867-
*pretend_size = 0;
1868-
return;
1869-
}
1870-
18711865
/* We must treat `__builtin_va_alist' as an anonymous arg. */
18721866

18731867
next_cum = *get_cumulative_args (args_so_far);
18741868
arc_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, true);
1875-
first_anon_arg = next_cum.arg_num;
1869+
first_anon_arg = TARGET_HS ? next_cum.last_reg : next_cum.arg_num;
18761870

18771871
if (FUNCTION_ARG_REGNO_P (first_anon_arg))
18781872
{
@@ -5215,6 +5209,7 @@ void arc_init_cumulative_args (CUMULATIVE_ARGS *cum,
52155209
int i;
52165210

52175211
cum->arg_num = 0;
5212+
cum->last_reg = 0;
52185213
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
52195214
{
52205215
cum->avail[i] = true;
@@ -5261,7 +5256,30 @@ arc_function_args_impl (CUMULATIVE_ARGS *cum,
52615256
return const0_rtx;
52625257

52635258
if (!named && TARGET_HS)
5264-
return NULL_RTX; /* all unamed arguments are passed on stack. */
5259+
{
5260+
reg_idx = cum->last_reg; /* for unamed args don't try fill up the reg-holes. */
5261+
nregs = arc_hard_regno_nregs (0, mode, type); /* only interested in the number of regs. */
5262+
if ((nregs == 2)
5263+
&& (mode != BLKmode) /* Only DI-like modes are interesting for us. */
5264+
&& (reg_idx & 1) /* Only for "non-aligned" registers. */
5265+
&& FUNCTION_ARG_REGNO_P (reg_idx + nregs - 1))
5266+
{
5267+
rtx reg1 = gen_rtx_REG (SImode, reg_idx);
5268+
rtx reg2 = gen_rtx_REG (SImode, reg_idx + 1);
5269+
rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
5270+
gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
5271+
5272+
if (advance)
5273+
{
5274+
cum->arg_num += nregs;
5275+
cum->avail[reg_idx] = false;
5276+
cum->avail[reg_idx + 1] = false;
5277+
cum->last_reg += nregs;
5278+
}
5279+
5280+
return gen_rtx_PARALLEL (mode, vec);
5281+
}
5282+
}
52655283

52665284
while (FUNCTION_ARG_REGNO_P (reg_idx))
52675285
{
@@ -5302,6 +5320,7 @@ arc_function_args_impl (CUMULATIVE_ARGS *cum,
53025320
{
53035321
cum->avail[reg_idx] = false;
53045322
}
5323+
cum->last_reg = reg_idx;
53055324
cum->arg_num += nregs;
53065325
}
53075326
return gen_rtx_REG (mode, reg_location);

gcc/config/arc/arc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,9 @@ typedef struct arc_args
924924
{
925925
/* Registers that are still available for parameter passing. */
926926
bool avail[FIRST_PSEUDO_REGISTER];
927+
/* HS-ABI: last set register. It is needed for passing the first
928+
anonymous arguments in regs. */
929+
unsigned int last_reg;
927930
/* Backwards compatibility: total number of used registers. */
928931
int arg_num;
929932
} CUMULATIVE_ARGS;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* { dg-do assemble } */
2+
#ifndef ENTRY
3+
#define ENTRY(nm) \
4+
.text ` \
5+
.align 4 ` \
6+
.globl nm ` \
7+
.type nm,@function ` \
8+
nm:
9+
#endif
10+
11+
#ifndef END
12+
#define END(name) .size name,.-name
13+
#endif
14+
15+
ENTRY(tsyscall)
16+
ENTRY(clone)
17+
add r0,r0,r1
18+
add r0,r0,r2
19+
add r0,r0,r3
20+
add r0,r0,r4
21+
add r0,r0,r5
22+
j_s.d [blink]
23+
add r0,r0,r6
24+
END(tsyscall)
25+
END(clone)
26+
27+
ENTRY(abidi)
28+
add.f r0,r1,1
29+
j_s.d [blink]
30+
adc r1,r2,0
31+
END(abidi)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* { dg-do run } */
2+
/* { dg-options "-O2" } */
3+
/* { dg-additional-sources "abitest.S" } */
4+
5+
extern long tsyscall (long int sysnum, ...);
6+
7+
int main (void)
8+
{
9+
long a;
10+
11+
a = tsyscall (1, 2, 3, 4, 5, 6, 7);
12+
13+
if (a != 28)
14+
return 1;
15+
return 0;
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* { dg-do run } */
2+
/* { dg-options "-O2" } */
3+
/* { dg-additional-sources "abitest.S" } */
4+
5+
extern int clone(int (*fn)(void *), void *child_stack,
6+
int flags, void *arg, ...);
7+
8+
int main (void)
9+
{
10+
int a = clone ((void *) 1, (void *)2, 3, (void *) 4, 5, 6, 7);
11+
if (a != 28)
12+
return 1;
13+
return 0;
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* { dg-do run } */
2+
/* { dg-options "-O2" } */
3+
/* { dg-additional-sources "abitest.S" } */
4+
5+
extern long long abidi (int a, ...);
6+
7+
int main (void)
8+
{
9+
long long a = 1;
10+
a = abidi (10, a);
11+
12+
if (a != 2)
13+
return 1;
14+
return 0;
15+
}

0 commit comments

Comments
 (0)