1 /*
2 * crypto_helper.c - emulate v8 Crypto Extensions instructions
3 *
4 * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 */
11
12 #include <stdlib.h>
13
14 #include "cpu.h"
15 #include "exec/exec-all.h"
16 #include "exec/helper-proto.h"
17 #include "qemu/aes.h"
18
19 union CRYPTO_STATE {
20 uint8_t bytes[16];
21 uint32_t words[4];
22 uint64_t l[2];
23 };
24
HELPER(crypto_aese)25 void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
26 uint32_t decrypt)
27 {
28 static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
29 static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
30
31 union CRYPTO_STATE rk;
32 union CRYPTO_STATE st;
33 int i;
34
35 rk.l[0] = float64_val(env->vfp.regs[rm]);
36 rk.l[1] = float64_val(env->vfp.regs[rm + 1]);
37 st.l[0] = float64_val(env->vfp.regs[rd]);
38 st.l[1] = float64_val(env->vfp.regs[rd + 1]);
39
40 assert(decrypt < 2);
41
42 /* xor state vector with round key */
43 rk.l[0] ^= st.l[0];
44 rk.l[1] ^= st.l[1];
45
46 /* combine ShiftRows operation and sbox substitution */
47 for (i = 0; i < 16; i++) {
48 st.bytes[i] = sbox[decrypt][rk.bytes[shift[decrypt][i]]];
49 }
50
51 env->vfp.regs[rd] = make_float64(st.l[0]);
52 env->vfp.regs[rd + 1] = make_float64(st.l[1]);
53 }
54
HELPER(crypto_aesmc)55 void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
56 uint32_t decrypt)
57 {
58 static uint32_t const mc[][256] = { {
59 /* MixColumns lookup table */
60 0x00000000, 0x03010102, 0x06020204, 0x05030306,
61 0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
62 0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
63 0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
64 0x30101020, 0x33111122, 0x36121224, 0x35131326,
65 0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
66 0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
67 0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
68 0x60202040, 0x63212142, 0x66222244, 0x65232346,
69 0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
70 0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
71 0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
72 0x50303060, 0x53313162, 0x56323264, 0x55333366,
73 0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
74 0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
75 0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
76 0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
77 0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
78 0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
79 0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
80 0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
81 0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
82 0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
83 0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
84 0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
85 0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
86 0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
87 0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
88 0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
89 0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
90 0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
91 0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
92 0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
93 0x97848413, 0x94858511, 0x91868617, 0x92878715,
94 0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
95 0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
96 0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
97 0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
98 0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
99 0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
100 0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
101 0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
102 0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
103 0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
104 0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
105 0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
106 0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
107 0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
108 0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
109 0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
110 0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
111 0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
112 0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
113 0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
114 0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
115 0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
116 0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
117 0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
118 0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
119 0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
120 0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
121 0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
122 0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
123 0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
124 }, {
125 /* Inverse MixColumns lookup table */
126 0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
127 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
128 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
129 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
130 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
131 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
132 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
133 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
134 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
135 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
136 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
137 0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
138 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
139 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
140 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
141 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
142 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
143 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
144 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
145 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
146 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
147 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
148 0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
149 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
150 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
151 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
152 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
153 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
154 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
155 0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
156 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
157 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
158 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
159 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
160 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
161 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
162 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
163 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
164 0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
165 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
166 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
167 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
168 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
169 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
170 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
171 0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
172 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
173 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
174 0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
175 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
176 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
177 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
178 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
179 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
180 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
181 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
182 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
183 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
184 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
185 0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
186 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
187 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
188 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
189 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
190 } };
191 union CRYPTO_STATE st;
192 int i;
193 st.l[0] = float64_val(env->vfp.regs[rm]);
194 st.l[1] = float64_val(env->vfp.regs[rm + 1]);
195
196 assert(decrypt < 2);
197
198 for (i = 0; i < 16; i += 4) {
199 st.words[i >> 2] = cpu_to_le32(
200 mc[decrypt][st.bytes[i]] ^
201 rol32(mc[decrypt][st.bytes[i + 1]], 8) ^
202 rol32(mc[decrypt][st.bytes[i + 2]], 16) ^
203 rol32(mc[decrypt][st.bytes[i + 3]], 24));
204 }
205
206 env->vfp.regs[rd] = make_float64(st.l[0]);
207 env->vfp.regs[rd + 1] = make_float64(st.l[1]);
208 }
209
210 /*
211 * SHA-1 logical functions
212 */
213
cho(uint32_t x,uint32_t y,uint32_t z)214 static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
215 {
216 return (x & (y ^ z)) ^ z;
217 }
218
par(uint32_t x,uint32_t y,uint32_t z)219 static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
220 {
221 return x ^ y ^ z;
222 }
223
maj(uint32_t x,uint32_t y,uint32_t z)224 static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
225 {
226 return (x & y) | ((x | y) & z);
227 }
228
HELPER(crypto_sha1_3reg)229 void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
230 uint32_t rm, uint32_t op)
231 {
232 union CRYPTO_STATE d;
233 union CRYPTO_STATE n;
234 union CRYPTO_STATE m;
235 d.l[0] = float64_val(env->vfp.regs[rd]);
236 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
237 n.l[0] = float64_val(env->vfp.regs[rn]);
238 n.l[1] = float64_val(env->vfp.regs[rn + 1]);
239 m.l[0] = float64_val(env->vfp.regs[rm]);
240 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
241
242 if (op == 3) { /* sha1su0 */
243 d.l[0] ^= d.l[1] ^ m.l[0];
244 d.l[1] ^= n.l[0] ^ m.l[1];
245 } else {
246 int i;
247
248 for (i = 0; i < 4; i++) {
249 uint32_t t;
250
251 switch (op) {
252 case 0: /* sha1c */
253 t = cho(d.words[1], d.words[2], d.words[3]);
254 break;
255 case 1: /* sha1p */
256 t = par(d.words[1], d.words[2], d.words[3]);
257 break;
258 case 2: /* sha1m */
259 t = maj(d.words[1], d.words[2], d.words[3]);
260 break;
261 default:
262 g_assert_not_reached();
263 }
264 t += rol32(d.words[0], 5) + n.words[0] + m.words[i];
265
266 n.words[0] = d.words[3];
267 d.words[3] = d.words[2];
268 d.words[2] = ror32(d.words[1], 2);
269 d.words[1] = d.words[0];
270 d.words[0] = t;
271 }
272 }
273 env->vfp.regs[rd] = make_float64(d.l[0]);
274 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
275 }
276
HELPER(crypto_sha1h)277 void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm)
278 {
279 union CRYPTO_STATE m;
280 m.l[0] = float64_val(env->vfp.regs[rm]);
281 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
282
283 m.words[0] = ror32(m.words[0], 2);
284 m.words[1] = m.words[2] = m.words[3] = 0;
285
286 env->vfp.regs[rd] = make_float64(m.l[0]);
287 env->vfp.regs[rd + 1] = make_float64(m.l[1]);
288 }
289
HELPER(crypto_sha1su1)290 void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm)
291 {
292 union CRYPTO_STATE d;
293 union CRYPTO_STATE m;
294 d.l[0] = float64_val(env->vfp.regs[rd]);
295 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
296 m.l[0] = float64_val(env->vfp.regs[rm]);
297 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
298
299 d.words[0] = rol32(d.words[0] ^ m.words[1], 1);
300 d.words[1] = rol32(d.words[1] ^ m.words[2], 1);
301 d.words[2] = rol32(d.words[2] ^ m.words[3], 1);
302 d.words[3] = rol32(d.words[3] ^ d.words[0], 1);
303
304 env->vfp.regs[rd] = make_float64(d.l[0]);
305 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
306 }
307
308 /*
309 * The SHA-256 logical functions, according to
310 * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
311 */
312
S0(uint32_t x)313 static uint32_t S0(uint32_t x)
314 {
315 return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
316 }
317
S1(uint32_t x)318 static uint32_t S1(uint32_t x)
319 {
320 return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
321 }
322
s0(uint32_t x)323 static uint32_t s0(uint32_t x)
324 {
325 return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
326 }
327
s1(uint32_t x)328 static uint32_t s1(uint32_t x)
329 {
330 return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
331 }
332
HELPER(crypto_sha256h)333 void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
334 uint32_t rm)
335 {
336 int i;
337 union CRYPTO_STATE d;
338 union CRYPTO_STATE n;
339 union CRYPTO_STATE m;
340 d.l[0] = float64_val(env->vfp.regs[rd]);
341 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
342 n.l[0] = float64_val(env->vfp.regs[rn]);
343 n.l[1] = float64_val(env->vfp.regs[rn + 1]);
344 m.l[0] = float64_val(env->vfp.regs[rm]);
345 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
346
347 for (i = 0; i < 4; i++) {
348 uint32_t t = cho(n.words[0], n.words[1], n.words[2]) + n.words[3]
349 + S1(n.words[0]) + m.words[i];
350
351 n.words[3] = n.words[2];
352 n.words[2] = n.words[1];
353 n.words[1] = n.words[0];
354 n.words[0] = d.words[3] + t;
355
356 t += maj(d.words[0], d.words[1], d.words[2]) + S0(d.words[0]);
357
358 d.words[3] = d.words[2];
359 d.words[2] = d.words[1];
360 d.words[1] = d.words[0];
361 d.words[0] = t;
362 }
363
364 env->vfp.regs[rd] = make_float64(d.l[0]);
365 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
366 }
367
HELPER(crypto_sha256h2)368 void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
369 uint32_t rm)
370 {
371 union CRYPTO_STATE d;
372 union CRYPTO_STATE n;
373 union CRYPTO_STATE m;
374 int i;
375
376 d.l[0] = float64_val(env->vfp.regs[rd]);
377 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
378 n.l[0] = float64_val(env->vfp.regs[rn]);
379 n.l[1] = float64_val(env->vfp.regs[rn + 1]);
380 m.l[0] = float64_val(env->vfp.regs[rm]);
381 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
382
383 for (i = 0; i < 4; i++) {
384 uint32_t t = cho(d.words[0], d.words[1], d.words[2]) + d.words[3]
385 + S1(d.words[0]) + m.words[i];
386
387 d.words[3] = d.words[2];
388 d.words[2] = d.words[1];
389 d.words[1] = d.words[0];
390 d.words[0] = n.words[3 - i] + t;
391 }
392
393 env->vfp.regs[rd] = make_float64(d.l[0]);
394 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
395 }
396
HELPER(crypto_sha256su0)397 void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm)
398 {
399 union CRYPTO_STATE d;
400 union CRYPTO_STATE m;
401 d.l[0] = float64_val(env->vfp.regs[rd]);
402 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
403 m.l[0] = float64_val(env->vfp.regs[rm]);
404 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
405
406 d.words[0] += s0(d.words[1]);
407 d.words[1] += s0(d.words[2]);
408 d.words[2] += s0(d.words[3]);
409 d.words[3] += s0(m.words[0]);
410
411 env->vfp.regs[rd] = make_float64(d.l[0]);
412 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
413 }
414
HELPER(crypto_sha256su1)415 void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn,
416 uint32_t rm)
417 {
418 union CRYPTO_STATE d;
419 union CRYPTO_STATE n;
420 union CRYPTO_STATE m;
421 d.l[0] = float64_val(env->vfp.regs[rd]);
422 d.l[1] = float64_val(env->vfp.regs[rd + 1]);
423 n.l[0] = float64_val(env->vfp.regs[rn]);
424 n.l[1] = float64_val(env->vfp.regs[rn + 1]);
425 m.l[0] = float64_val(env->vfp.regs[rm]);
426 m.l[1] = float64_val(env->vfp.regs[rm + 1]);
427
428 d.words[0] += s1(m.words[2]) + n.words[1];
429 d.words[1] += s1(m.words[3]) + n.words[2];
430 d.words[2] += s1(d.words[0]) + n.words[3];
431 d.words[3] += s1(d.words[1]) + m.words[0];
432
433 env->vfp.regs[rd] = make_float64(d.l[0]);
434 env->vfp.regs[rd + 1] = make_float64(d.l[1]);
435 }
436