/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1987 Sun Microsystems, Inc.
 */

#ident	"%Z%%M%	%I%	%E% SMI"

	.file	"stret.s"

#include <sys/asm_linkage.h>

#define FROM	%o0
#define SIZE	%o1
#define TO	%i0
#define MEMWORD	%o3	/* use o-registers as temps */
#define TEMP	%o4
#define TEMP2	%o5
#define UNIMP	0
#define MASK	0x00000fff
#define STRUCT_VAL_OFF	(16*4)
#if STRET4
#    define BYTES_PER_MOVE	4
#    define LD	ld
#    define ST	st
	ENTRY2(.stret4,.stret8)
#endif
#if STRET2
#    define BYTES_PER_MOVE	2
#    define LD	lduh
#    define ST	sth
	ENTRY(.stret2)
#endif
#if STRET1
#    define BYTES_PER_MOVE	1
#    define LD	ldub
#    define ST	stb
	ENTRY(.stret1)
#endif

	/*
	 * see if key matches: if not,
	 * structure value not expected,
	 * so just return
	 */
	ld	[%i7+8],MEMWORD
	and	SIZE,MASK,TEMP
	sethi	%hi(UNIMP),TEMP2
	or      TEMP,TEMP2,TEMP2
	cmp     TEMP2,MEMWORD
	bne	.LE12
	.empty
	/*
	 * set expected return value
	 */
.L14:
	ld	[%fp+STRUCT_VAL_OFF],TO		/* (DELAY SLOT) */
	/* 
	 * copy the struct using the same loop the compiler does
	 * for large structure assignment
	 */
.L15:
	subcc	SIZE,BYTES_PER_MOVE,SIZE
	LD	[FROM+SIZE],TEMP
	bg	.L15
	ST	TEMP,[TO+SIZE]			/* (DELAY SLOT) */
	/* bump return address */
	add	%i7,0x4,%i7
.LE12:
	jmp	%i7+8
	restore

#if STRET4
	SET_SIZE(.stret4)
	SET_SIZE(.stret8)
#endif
#if STRET2
	SET_SIZE(.stret2)
#endif
#if STRET1
	SET_SIZE(.stret1)
#endif
