1bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata/*
2bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * This file is part of ltrace.
3982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
4bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * Copyright (C) 2008,2009 Juan Cespedes
5bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * Copyright (C) 2006 Steve Fink
6bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * Copyright (C) 2006 Ian Wienand
7bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata *
8bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * This program is free software; you can redistribute it and/or
9bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * modify it under the terms of the GNU General Public License as
10bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * published by the Free Software Foundation; either version 2 of the
11bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * License, or (at your option) any later version.
12bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata *
13bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * This program is distributed in the hope that it will be useful, but
14bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
15bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * General Public License for more details.
17bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata *
18bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * You should have received a copy of the GNU General Public License
19bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * along with this program; if not, write to the Free Software
20bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata * 02110-1301 USA
22bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata */
23bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
24bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <stdlib.h>
25bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <assert.h>
26bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <sys/rse.h>
27bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <ptrace.h>
28bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <string.h>
29bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include <errno.h>
30bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
31bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include "backend.h"
32bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include "fetch.h"
33bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include "type.h"
34bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include "proc.h"
35bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata#include "value.h"
36bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
37bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastruct fetch_context {
38bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	arch_addr_t stack_pointer;
39bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct pt_all_user_regs regs;
40a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	enum param_pack_flavor ppflavor;
41bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
42bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* Return values larger than 256 bits (except HFAs of up to 8
43bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * elements) are returned in a buffer allocated by the
44bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * caller. A pointer to the buffer is passed to the called
45bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * procedure in r8. This register is not guaranteed to be
46bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * preserved by the called procedure.  */
47bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned long r8;
48bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
49bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	int slot_n;
50bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	int flt;
51bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata};
52bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
53bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataunion cfm_t {
54bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct {
55bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long sof:7;
56bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long sol:7;
57bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long sor:4;
58bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long rrb_gr:7;
59bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long rrb_fr:7;
60bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned long rrb_pr:6;
61bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	} cfm;
62bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned long value;
63bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata};
64bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
65bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
66929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_context_init(struct process *proc, struct fetch_context *context)
67bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
68bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	context->slot_n = 0;
69bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	context->flt = 8;
70bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0)
71bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
72bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	context->stack_pointer = (void *)(context->regs.gr[12] + 16);
73a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	context->ppflavor = PARAM_PACK_ARGS;
74bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
75bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
76bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
77bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
78bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastruct fetch_context *
79929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_init(enum tof type, struct process *proc,
80bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		    struct arg_type_info *ret_info)
81bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
82bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct fetch_context *context = malloc(sizeof(*context));
83bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (context == NULL
84bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	    || fetch_context_init(proc, context) < 0) {
85bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		free(context);
86bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return NULL;
87bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
88bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	context->r8 = context->regs.gr[8];
89bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
90bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return context;
91bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
92bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
93bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastruct fetch_context *
94929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_clone(struct process *proc,
95bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		     struct fetch_context *context)
96bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
97bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct fetch_context *clone = malloc(sizeof(*context));
98bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (clone == NULL)
99bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return NULL;
100bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	*clone = *context;
101bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return clone;
102bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
103bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
104bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataint
105929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_stack_slot(struct fetch_context *ctx, struct process *proc,
106bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		    struct arg_type_info *info, struct value *valuep)
107bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
108bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t al = type_alignof(proc, info);
109bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t sz = type_sizeof(proc, info);
110bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (al == (size_t)-1 || sz == (size_t)-1)
111bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
112bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
113bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	errno = 0;
114bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	long value = ptrace(PTRACE_PEEKDATA, proc->pid, ctx->stack_pointer, 0);
115bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (value == -1 && errno != 0)
116bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
117bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	ctx->stack_pointer += 8;
118bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	value_set_word(valuep, value);
119bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
120bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
121bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
122bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
123bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
124929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_reg(struct fetch_context *ctx, struct process *proc,
125bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	     struct arg_type_info *info, struct value *valuep)
126bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
127bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (ctx->slot_n >= 8)
128bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return allocate_stack_slot(ctx, proc, info, valuep);
129bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
130bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	int reg_num = ctx->slot_n++;
131bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (ctx->slot_n == 8)
132bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		ctx->flt = 16;
133bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (valuep == NULL)
134bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return 0;
135bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
136bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* This would normally be brought over from asm/ptrace.h, but
137bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * when we do, we get namespace conflicts between asm/fpu.h
138bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * and libunwind.  */
139bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	enum { PT_AUR_BSP = 17 };
140bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
141bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	union cfm_t cfm = { .value = ctx->regs.cfm };
142bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned long *bsp = (unsigned long *)ctx->regs.ar[PT_AUR_BSP];
143bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned long idx = -cfm.cfm.sof + reg_num;
144bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned long *ptr = ia64_rse_skip_regs(bsp, idx);
145bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	errno = 0;
146bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	long ret = ptrace(PTRACE_PEEKDATA, proc->pid, ptr, 0);
147bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (ret == -1 && errno != 0)
148bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
149bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
150bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	value_set_word(valuep, ret);
151bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
152bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
153bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
154bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
155929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatacopy_aggregate_part(struct fetch_context *ctx, struct process *proc,
156bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		    unsigned char *buf, size_t size)
157bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
158bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t slots = (size + 7) / 8;
159bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
160bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	while (slots-- > 0) {
161bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		size_t chunk_sz = size > 8 ? 8 : size;
162bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		size -= 8;
163bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
164bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		struct value tmp;
165bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_init(&tmp, proc, NULL, long_info, 0);
166bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		int rc = allocate_reg(ctx, proc, long_info, &tmp);
167bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc >= 0) {
168bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			memcpy(buf, value_get_data(&tmp, NULL), chunk_sz);
169bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			buf += 8;
170bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		}
171bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_destroy(&tmp);
172bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc < 0)
173bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return -1;
174bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
175bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
176bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
177bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
178bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
179929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_arg(struct fetch_context *ctx, struct process *proc,
180bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	     struct arg_type_info *info, struct value *valuep)
181bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
182bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t sz = type_sizeof(proc, info);
183bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t align = type_alignof(proc, info);
184bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (sz == (size_t)-1 || align == (size_t)-1)
185bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
186bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
187bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned char *buf = value_reserve(valuep, sz);
188bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (buf == NULL)
189bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
190bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
191bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	assert(align == 0 || align == 1 || align == 2 || align == 4
192bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	       || align == 8 || align == 16);
193bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
194bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* For aggregates with an external alignment of 16 bytes, the
195bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * Next Even policy is used.  128-bit integers use the Next
196bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * Even policy as well.  */
197bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (align == 16 && ctx->slot_n % 2 != 0)
198bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		allocate_reg(ctx, proc, info, NULL);
199bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
200bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	int rc= copy_aggregate_part(ctx, proc, buf, sz);
201bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
202bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return rc;
203bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
204bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
205bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata/* Stolen from David Mosberger's utrace tool, which he released under
206bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata   the GPL
207bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata   (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */
208bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic inline double
209bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatafpreg_to_double (struct ia64_fpreg *fp) {
210bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	double result;
211bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp));
212bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return result;
213bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
214bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
215bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
216929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_float(struct fetch_context *ctx, struct process *proc,
217bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	       struct arg_type_info *info, struct value *valuep,
218bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	       int take_slot)
219bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
220bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* The actual parameter is passed in the next available
221bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * floating-point parameter register, if one is
222bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * available. Floating-point parameter registers are allocated
223bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * as needed from the range f8-f15, starting with f8.  */
224a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	/* Any register parameters corresponding to a
225a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	 * variable-argument specification are passed in GRs.  */
226a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	if (ctx->flt > 15 || ctx->ppflavor == PARAM_PACK_VARARGS)
227bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		/* If all available floating-point parameter registers
228bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		 * have been used, the actual parameter is passed in
229bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		 * the appropriate general register(s).  */
230bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return allocate_reg(ctx, proc, info, valuep);
231bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
232bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	union {
233bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		double d;
234bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		float f;
235bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		char buf[0];
236bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	} u = { .d = fpreg_to_double(&ctx->regs.fr[ctx->flt++]) };
237bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (take_slot)
238bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		allocate_reg(ctx, proc, info, NULL);
239bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
240bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (info->type == ARGTYPE_FLOAT)
241bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		u.f = u.d;
242bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	else
243bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		assert(info->type == ARGTYPE_DOUBLE);
244bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
245bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (value_reserve(valuep, sizeof(u)) == NULL)
246bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
247bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	memmove(value_get_raw_data(valuep), u.buf, sizeof(u));
248bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
249bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
250bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
251bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
252bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
253929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_hfa(struct fetch_context *ctx, struct process *proc,
254bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	     struct arg_type_info *info, struct value *valuep,
255bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	     enum arg_type hfa_type, size_t hfa_count)
256bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
257bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t sz = type_sizeof(proc, info);
258bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (sz == (size_t)-1)
259bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
260bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
261bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* If an actual parameter is known to correspond to an HFA
262bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * formal parameter, each element is passed in the next
263bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * available floating-point argument register, until the eight
264bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * argument registers are exhausted. The remaining elements of
265bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * the aggregate are passed in output GRs, according to the
266bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * normal conventions.
267bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 *
268bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * Because HFAs are mapped to parameter slots as aggregates,
269bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * single-precision HFAs will be allocated with two
270bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * floating-point values in each parameter slot, but only one
271bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * value per register.
272bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 *
273bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * It is possible for the first of two values in a parameter
274bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * slot to occupy the last available floating- point parameter
275bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * register. In this case, the second value is passed in its
276bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * designated GR, but the half of the GR that would have
277bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * contained the first value is undefined.  */
278bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
279bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t slot_off = 0;
280bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
281bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	unsigned char *buf = value_reserve(valuep, sz);
282bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (buf == NULL)
283bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
284bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
285bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct arg_type_info *hfa_info = type_get_simple(hfa_type);
286bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t hfa_sz = type_sizeof(proc, hfa_info);
287bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
288bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* Pass in register the part that we can.  */
289bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	while (ctx->flt <= 15 && hfa_count > 0) {
290bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		struct value tmp;
291bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_init(&tmp, proc, NULL, hfa_info, 0);
292bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		int rc = allocate_float(ctx, proc, hfa_info, &tmp, 0);
293bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc >= 0) {
294bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			memcpy(buf, value_get_data(&tmp, NULL), hfa_sz);
295bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			slot_off += hfa_sz;
296bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			buf += hfa_sz;
297bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			hfa_count--;
298bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
299bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			/* Scratch each fully used slot.  */
300bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			while (slot_off >= 8) {
301bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata				if (allocate_reg(ctx, proc, info, NULL) < 0)
302bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata					rc = -1;
303bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata				slot_off -= 8;
304bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			}
305bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		}
306bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_destroy(&tmp);
307bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc < 0)
308bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return -1;
309bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
310bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
311bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* If we have half-slot opened (the case where odd
312bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * ARGTYPE_FLOAT member fits into the last floating point
313bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * register, and the following even member does not), finish
314bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * it first.  */
315bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
316bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (slot_off != 0 && hfa_count > 0) {
317bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		struct value tmp;
318bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_init(&tmp, proc, NULL, long_info, 0);
319bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		int rc = allocate_reg(ctx, proc, long_info, &tmp);
320bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc >= 0) {
321bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			unsigned char *data = value_get_data(&tmp, NULL);
322bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			memcpy(buf, data, 8 - slot_off);
323bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			buf += 8 - slot_off;
324bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			hfa_count--;
325bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		}
326bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_destroy(&tmp);
327bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (rc < 0) {
328bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return -1;
329bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		}
330bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
331bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
332bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* The rest is passed in registers and on stack.  */
333bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t rest = hfa_count * hfa_sz;
334bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return copy_aggregate_part(ctx, proc, buf, rest);
335bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
336bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
337bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatastatic int
338929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_ret(struct fetch_context *ctx, struct process *proc,
339bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	     struct arg_type_info *info, struct value *valuep)
340bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
341bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	size_t sz = type_sizeof(proc, info);
342bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (sz == (size_t)-1)
343bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
344bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
345bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* Homogeneous floating-point aggregates [...] are returned in
346bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * floating-point registers, provided the array or structure
347bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * contains no more than eight individual values.  The
348bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * elements of the aggregate are placed in successive
349bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * floating-point registers, beginning with f8.  */
350bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) {
351bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		size_t hfa_size;
352982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata		struct arg_type_info *hfa_info
353982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata			= type_get_hfa_type(info, &hfa_size);
354982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata		if (hfa_info != NULL && hfa_size <= 8)
355bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return allocate_hfa(ctx, proc, info, valuep,
356982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata					    hfa_info->type, hfa_size);
357bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
358bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
359bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	/* Integers and pointers are passed in r8.  128-bit integers
360bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * are passed in r8 and r9.  Aggregates of up to 256 bits [32
361bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	 * bytes] are passed in registers r8...r11.  */
362bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (sz <= 32) {
363bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		unsigned char *buf = value_reserve(valuep, sz);
364bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		if (buf == NULL)
365bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return -1;
366bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		memcpy(buf, ctx->regs.gr + 8, sz);
367bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return 0;
368bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
369bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
370bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (value_pass_by_reference(valuep) < 0)
371bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
372bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	value_set_word(valuep, ctx->r8);
373bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return 0;
374bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
375bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
376bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataint
377bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
378929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		    struct process *proc,
379bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		    struct arg_type_info *info, struct value *valuep)
380bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
381bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	switch (info->type) {
382982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata		struct arg_type_info *hfa_info;
383bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		size_t hfa_size;
384bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
385bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_VOID:
386bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		value_set_word(valuep, 0);
387bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return 0;
388bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
389bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_FLOAT:
390bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_DOUBLE:
391bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return allocate_float(ctx, proc, info, valuep, 1);
392bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
393bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_STRUCT:
394982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata		hfa_info = type_get_hfa_type(info, &hfa_size);
395982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata		if (hfa_info != NULL)
396bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata			return allocate_hfa(ctx, proc, info, valuep,
397982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata					    hfa_info->type, hfa_size);
398bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		/* Fall through.  */
399bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_CHAR:
400bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_SHORT:
401bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_USHORT:
402bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_INT:
403bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_UINT:
404bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_LONG:
405bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_ULONG:
406b50f0e143c6d0b99031b880b8ec85c0995a06033Petr Machata	case ARGTYPE_POINTER:
407b50f0e143c6d0b99031b880b8ec85c0995a06033Petr Machata		return allocate_arg(ctx, proc, info, valuep);
408bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
409bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_ARRAY:
410bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		/* Arrays decay into pointers.  XXX Fortran?  */
4115b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias	default:
4125b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias		assert(info->type != info->type);
413bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		abort();
414bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
415bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
416bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
417bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataint
418bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type,
419929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		  struct process *proc, struct arg_type_info *info,
420bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		  struct value *valuep)
421bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
422bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	if (fetch_context_init(proc, ctx) < 0)
423bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return -1;
424bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
425bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	switch (info->type) {
426bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_VOID:
427bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_FLOAT:
428bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_DOUBLE:
429bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		/* The rules for returning those types are the same as
430bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		 * for passing them in arguments.  */
431bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return arch_fetch_arg_next(ctx, type, proc, info, valuep);
432bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
433bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_CHAR:
434bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_SHORT:
435bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_USHORT:
436bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_INT:
437bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_UINT:
438bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_LONG:
439bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_ULONG:
440bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_POINTER:
441bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_STRUCT:
442bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		return allocate_ret(ctx, proc, info, valuep);
443bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
444bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	case ARGTYPE_ARRAY:
445bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		/* Arrays decay into pointers.  XXX Fortran?  */
446bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		assert(info->type != ARGTYPE_ARRAY);
447bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata		abort();
448bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	}
449bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	assert("unhandled type");
450bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	abort();
451bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	return arch_fetch_arg_next(ctx, type, proc, info, valuep);
452bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
453bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata
454bd3752795ee71477adb76c1f1af17b9da3964004Petr Machatavoid
455bd3752795ee71477adb76c1f1af17b9da3964004Petr Machataarch_fetch_arg_done(struct fetch_context *context)
456bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata{
457bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata	free(context);
458bd3752795ee71477adb76c1f1af17b9da3964004Petr Machata}
459a400a7c858f81b3be051a37011d88f8639bee598Petr Machata
460a400a7c858f81b3be051a37011d88f8639bee598Petr Machataint
461a400a7c858f81b3be051a37011d88f8639bee598Petr Machataarch_fetch_param_pack_start(struct fetch_context *context,
462a400a7c858f81b3be051a37011d88f8639bee598Petr Machata			    enum param_pack_flavor ppflavor)
463a400a7c858f81b3be051a37011d88f8639bee598Petr Machata{
464a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	context->ppflavor = ppflavor;
465a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	return 0;
466a400a7c858f81b3be051a37011d88f8639bee598Petr Machata}
467a400a7c858f81b3be051a37011d88f8639bee598Petr Machata
468a400a7c858f81b3be051a37011d88f8639bee598Petr Machatavoid
469a400a7c858f81b3be051a37011d88f8639bee598Petr Machataarch_fetch_param_pack_end(struct fetch_context *context)
470a400a7c858f81b3be051a37011d88f8639bee598Petr Machata{
471a400a7c858f81b3be051a37011d88f8639bee598Petr Machata	context->ppflavor = PARAM_PACK_ARGS;
472a400a7c858f81b3be051a37011d88f8639bee598Petr Machata}
473