1/*	$NetBSD$	*/
2/*-
3 * Copyright (c) 2011 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas of 3am Software Foundry.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "opt_altivec.h"
32
33RCSID("$NetBSD$")
34
35#ifdef ALTIVEC
36/*
37 * LINTSTUB: void vec_load_from_vreg(const struct vreg *vreg);
38 */
39ENTRY(vec_load_from_vreg)
40	/*
41	 * Restore VSCR by first loading it into a vector and then into
42	 * VSCR. (this needs to done before loading the user's vector
43	 * registers since we need to use a scratch vector register)
44	 */
45	vxor %v0,%v0,%v0
46	li %r4,VREG_VSCR; lvewx %v0,%r3,%r4
47	mtvscr %v0
48
49	/*
50	 * Now load the vector registers.  We do it this way so that if on
51	 * a superscalar cpu, we can get some concurrency.
52	 */
53	li %r4,VREG_V0; lvx %v0,%r3,%r4
54	li %r5,VREG_V1; lvx %v1,%r3,%r5
55	li %r6,VREG_V2; lvx %v2,%r3,%r6
56	li %r7,VREG_V3; lvx %v3,%r3,%r7
57
58	li %r4,VREG_V4; lvx %v4,%r3,%r4
59	li %r5,VREG_V5; lvx %v5,%r3,%r5
60	li %r6,VREG_V6; lvx %v6,%r3,%r6
61	li %r7,VREG_V7; lvx %v7,%r3,%r7
62
63	li %r4,VREG_V8; lvx %v8,%r3,%r4
64	li %r5,VREG_V9; lvx %v9,%r3,%r5
65	li %r6,VREG_V10; lvx %v10,%r3,%r6
66	li %r7,VREG_V11; lvx %v11,%r3,%r7
67
68	li %r4,VREG_V12; lvx %v12,%r3,%r4
69	li %r5,VREG_V13; lvx %v13,%r3,%r5
70	li %r6,VREG_V14; lvx %v14,%r3,%r6
71	li %r7,VREG_V15; lvx %v15,%r3,%r7
72
73	li %r4,VREG_V16; lvx %v16,%r3,%r4
74	li %r5,VREG_V17; lvx %v17,%r3,%r5
75	li %r6,VREG_V18; lvx %v18,%r3,%r6
76	li %r7,VREG_V19; lvx %v19,%r3,%r7
77
78	li %r4,VREG_V20; lvx %v20,%r3,%r4
79	li %r5,VREG_V21; lvx %v21,%r3,%r5
80	li %r6,VREG_V22; lvx %v22,%r3,%r6
81	li %r7,VREG_V23; lvx %v23,%r3,%r7
82
83	li %r4,VREG_V24; lvx %v24,%r3,%r4
84	li %r5,VREG_V25; lvx %v25,%r3,%r5
85	li %r6,VREG_V26; lvx %v26,%r3,%r6
86	li %r7,VREG_V27; lvx %v27,%r3,%r7
87
88	li %r4,VREG_V28; lvx %v28,%r3,%r4
89	li %r5,VREG_V29; lvx %v29,%r3,%r5
90	li %r6,VREG_V30; lvx %v30,%r3,%r6
91	li %r7,VREG_V31; lvx %v31,%r3,%r7
92
93	isync
94	blr
95END(vec_load_from_vreg)
96
97/*
98 * LINTSTUB: void vec_unload_to_vreg(struct vreg *vreg);
99 */
100ENTRY(vec_unload_to_vreg)
101	/*
102	 * Store the vector registers.  We do it this way so that if on
103	 * a superscalar cpu, we can get some concurrency.
104	 */
105	li %r4,VREG_V0; stvx %v0,%r3,%r4
106	li %r5,VREG_V1; stvx %v1,%r3,%r5
107	li %r6,VREG_V2; stvx %v2,%r3,%r6
108	li %r7,VREG_V3; stvx %v3,%r3,%r7
109
110	li %r4,VREG_V4; stvx %v4,%r3,%r4
111	li %r5,VREG_V5; stvx %v5,%r3,%r5
112	li %r6,VREG_V6; stvx %v6,%r3,%r6
113	li %r7,VREG_V7; stvx %v7,%r3,%r7
114
115	li %r4,VREG_V8; stvx %v8,%r3,%r4
116	li %r5,VREG_V9; stvx %v9,%r3,%r5
117	li %r6,VREG_V10; stvx %v10,%r3,%r6
118	li %r7,VREG_V11; stvx %v11,%r3,%r7
119
120	li %r4,VREG_V12; stvx %v12,%r3,%r4
121	li %r5,VREG_V13; stvx %v13,%r3,%r5
122	li %r6,VREG_V14; stvx %v14,%r3,%r6
123	li %r7,VREG_V15; stvx %v15,%r3,%r7
124
125	li %r4,VREG_V16; stvx %v16,%r3,%r4
126	li %r5,VREG_V17; stvx %v17,%r3,%r5
127	li %r6,VREG_V18; stvx %v18,%r3,%r6
128	li %r7,VREG_V19; stvx %v19,%r3,%r7
129
130	li %r4,VREG_V20; stvx %v20,%r3,%r4
131	li %r5,VREG_V21; stvx %v21,%r3,%r5
132	li %r6,VREG_V22; stvx %v22,%r3,%r6
133	li %r7,VREG_V23; stvx %v23,%r3,%r7
134
135	li %r4,VREG_V24; stvx %v24,%r3,%r4
136	li %r5,VREG_V25; stvx %v25,%r3,%r5
137	li %r6,VREG_V26; stvx %v26,%r3,%r6
138	li %r7,VREG_V27; stvx %v27,%r3,%r7
139
140	li %r4,VREG_V28; stvx %v28,%r3,%r4
141	li %r5,VREG_V29; stvx %v29,%r3,%r5
142	li %r6,VREG_V30; stvx %v30,%r3,%r6
143	li %r7,VREG_V31; stvx %v31,%r3,%r7
144
145	/*
146	 * Save VSCR but remember to restore the vector that used to save it.
147	 */
148	mfvscr %v31
149	li %r4,VREG_VSCR; stvewx %v31,%r3,%r4	/* low word only */
150
151	lvx %v31,%r3,%r7	/* restore v31 */
152
153	isync
154	blr
155END(vec_load_from_vreg)
156#endif /* ALTIVEC */
157