1/* Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
2
3This file is part of GCC.
4
5GCC is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2, or (at your option)
8any later version.
9
10GCC is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GCC; see the file COPYING.  If not, write to
17the Free Software Foundation, 51 Franklin Street, Fifth Floor,
18Boston, MA 02110-1301, USA.  */
19
20/* As a special exception, if you include this header file into source
21   files compiled by GCC, this header file does not by itself cause
22   the resulting executable to be covered by the GNU General Public
23   License.  This exception does not however invalidate any other
24   reasons why the executable file might be covered by the GNU General
25   Public License.  */
26
27/* ushmedia.h: Intrinsics corresponding to SHmedia instructions that
28   may be executed in both user and privileged mode.  */
29
30#ifndef _USHMEDIA_H
31#define _USHMEDIA_H
32
33#if __SHMEDIA__
34#if ! __SH4_NO_FPU
35typedef float __GCC_FV __attribute__ ((vector_size (4 * sizeof (float))));
36typedef float __GCC_MTRX __attribute__ ((vector_size (16 * sizeof (float))));
37#endif
38
39static __inline unsigned long long
40sh_media_MABS_L (unsigned long long mm)
41{
42  typedef float v2si __attribute__ ((mode(V2SI)));
43
44  return (unsigned long long) __builtin_absv2si2 ((v2si) mm);
45}
46
47static __inline unsigned long long
48sh_media_MABS_W (unsigned long long mm)
49{
50  typedef float v4hi __attribute__ ((mode(V4HI)));
51
52  return (unsigned long long) __builtin_absv4hi2 ((v4hi) mm);
53}
54
55static __inline unsigned long long
56sh_media_MADD_L (unsigned long long mm, unsigned long long mn)
57{
58  typedef float v2si __attribute__ ((mode(V2SI)));
59
60  return (unsigned long long) __builtin_addv2si3 ((v2si) mm, (v2si) mn);
61}
62
63static __inline unsigned long long
64sh_media_MADD_W (unsigned long long mm, unsigned long long mn)
65{
66  typedef float v4hi __attribute__ ((mode(V4HI)));
67
68  return (unsigned long long) __builtin_addv4hi3 ((v4hi) mm, (v4hi) mn);
69}
70
71static __inline unsigned long long
72sh_media_MADDS_L (unsigned long long mm, unsigned long long mn)
73{
74  typedef float v2si __attribute__ ((mode(V2SI)));
75
76  return (unsigned long long) __builtin_ssaddv2si3 ((v2si) mm, (v2si) mn);
77}
78
79static __inline unsigned long long
80sh_media_MADDS_UB (unsigned long long mm, unsigned long long mn)
81{
82  typedef float v8qi __attribute__ ((mode(V8QI)));
83
84  return (unsigned long long) __builtin_usaddv8qi3 ((v8qi) mm, (v8qi) mn);
85}
86
87static __inline unsigned long long
88sh_media_MADDS_W (unsigned long long mm, unsigned long long mn)
89{
90  typedef float v4hi __attribute__ ((mode(V4HI)));
91
92  return (unsigned long long) __builtin_ssaddv4hi3 ((v4hi) mm, (v4hi) mn);
93}
94
95static __inline unsigned long long
96sh_media_MCMPEQ_B (unsigned long long mm, unsigned long long mn)
97{
98  typedef float v8qi __attribute__ ((mode(V8QI)));
99
100  return (unsigned long long) __builtin_sh_media_MCMPEQ_B ((v8qi) mm,
101							   (v8qi) mn);
102}
103
104static __inline unsigned long long
105sh_media_MCMPEQ_L (unsigned long long mm, unsigned long long mn)
106{
107  typedef float v2si __attribute__ ((mode(V2SI)));
108
109  return (unsigned long long) __builtin_sh_media_MCMPEQ_L ((v2si) mm,
110							   (v2si) mn);
111}
112
113static __inline unsigned long long
114sh_media_MCMPEQ_W (unsigned long long mm, unsigned long long mn)
115{
116  typedef float v4hi __attribute__ ((mode(V4HI)));
117
118  return (unsigned long long) __builtin_sh_media_MCMPEQ_W ((v4hi) mm,
119							   (v4hi) mn);
120}
121
122static __inline unsigned long long
123sh_media_MCMPGT_UB (unsigned long long mm, unsigned long long mn)
124{
125  typedef float v8qi __attribute__ ((mode(V8QI)));
126
127  return (unsigned long long) __builtin_sh_media_MCMPGT_UB ((v8qi) mm,
128							   (v8qi) mn);
129}
130
131static __inline unsigned long long
132sh_media_MCMPGT_L (unsigned long long mm, unsigned long long mn)
133{
134  typedef float v2si __attribute__ ((mode(V2SI)));
135
136  return (unsigned long long) __builtin_sh_media_MCMPGT_L ((v2si) mm,
137							   (v2si) mn);
138}
139
140static __inline unsigned long long
141sh_media_MCMPGT_W (unsigned long long mm, unsigned long long mn)
142{
143  typedef float v4hi __attribute__ ((mode(V4HI)));
144
145  return (unsigned long long) __builtin_sh_media_MCMPGT_W ((v4hi) mm,
146							   (v4hi) mn);
147}
148
149#define sh_media_MCMV __builtin_sh_media_MCMV
150
151static __inline unsigned long long
152sh_media_MCNVS_LW (unsigned long long mm, unsigned long long mn)
153{
154  typedef float v2si __attribute__ ((mode(V2SI)));
155  typedef unsigned int uv2si __attribute__ ((mode(V2SI)));
156
157  return (unsigned long long) __builtin_sh_media_MCNVS_LW ((v2si) mm,
158							   (uv2si) mn);
159}
160
161static __inline unsigned long long
162sh_media_MCNVS_WB (unsigned long long mm, unsigned long long mn)
163{
164  typedef float v4hi __attribute__ ((mode(V4HI)));
165
166  return (unsigned long long) __builtin_sh_media_MCNVS_WB ((v4hi) mm,
167							   (v4hi) mn);
168}
169
170static __inline unsigned long long
171sh_media_MCNVS_WUB (unsigned long long mm, unsigned long long mn)
172{
173  typedef float v4hi __attribute__ ((mode(V4HI)));
174
175  return (unsigned long long) __builtin_sh_media_MCNVS_WUB ((v4hi) mm,
176							    (v4hi) mn);
177}
178
179static __inline unsigned long long
180sh_media_MEXTR1 (unsigned long long mm, unsigned long long mn)
181{
182  typedef float v8qi __attribute__ ((mode(V8QI)));
183
184  return (unsigned long long) __builtin_sh_media_MEXTR1 ((v8qi) mm,
185							 (v8qi) mn);
186}
187
188static __inline unsigned long long
189sh_media_MEXTR2 (unsigned long long mm, unsigned long long mn)
190{
191  typedef float v8qi __attribute__ ((mode(V8QI)));
192
193  return (unsigned long long) __builtin_sh_media_MEXTR2 ((v8qi) mm,
194							 (v8qi) mn);
195}
196
197static __inline unsigned long long
198sh_media_MEXTR3 (unsigned long long mm, unsigned long long mn)
199{
200  typedef float v8qi __attribute__ ((mode(V8QI)));
201
202  return (unsigned long long) __builtin_sh_media_MEXTR3 ((v8qi) mm,
203							 (v8qi) mn);
204}
205
206static __inline unsigned long long
207sh_media_MEXTR4 (unsigned long long mm, unsigned long long mn)
208{
209  typedef float v8qi __attribute__ ((mode(V8QI)));
210
211  return (unsigned long long) __builtin_sh_media_MEXTR4 ((v8qi) mm,
212							 (v8qi) mn);
213}
214
215static __inline unsigned long long
216sh_media_MEXTR5 (unsigned long long mm, unsigned long long mn)
217{
218  typedef float v8qi __attribute__ ((mode(V8QI)));
219
220  return (unsigned long long) __builtin_sh_media_MEXTR5 ((v8qi) mm,
221							 (v8qi) mn);
222}
223
224static __inline unsigned long long
225sh_media_MEXTR6 (unsigned long long mm, unsigned long long mn)
226{
227  typedef float v8qi __attribute__ ((mode(V8QI)));
228
229  return (unsigned long long) __builtin_sh_media_MEXTR6 ((v8qi) mm,
230							 (v8qi) mn);
231}
232
233static __inline unsigned long long
234sh_media_MEXTR7 (unsigned long long mm, unsigned long long mn)
235{
236  typedef float v8qi __attribute__ ((mode(V8QI)));
237
238  return (unsigned long long) __builtin_sh_media_MEXTR7 ((v8qi) mm,
239							 (v8qi) mn);
240}
241
242static __inline unsigned long long
243sh_media_MMACFX_WL (unsigned long long mm, unsigned long long mn,
244		    unsigned long long mw)
245{
246  typedef float v2hi __attribute__ ((mode(V2HI)));
247  typedef float v2si __attribute__ ((mode(V2SI)));
248  typedef unsigned int uv2si __attribute__ ((mode(V2SI)));
249
250  long mm_l = (long) mm;
251  long mn_l = (long) mn;
252
253  return ((unsigned long long)
254    __builtin_sh_media_MMACFX_WL ((v2hi) mm_l, (v2hi) mn_l,
255				  (uv2si) mw));
256}
257
258static __inline unsigned long long
259sh_media_MMACNFX_WL (unsigned long long mm, unsigned long long mn,
260		     unsigned long long mw)
261{
262  typedef float v2hi __attribute__ ((mode(V2HI)));
263  typedef float v2si __attribute__ ((mode(V2SI)));
264  typedef unsigned int uv2si __attribute__ ((mode(V2SI)));
265
266  long mm_l = (long) mm;
267  long mn_l = (long) mn;
268
269  return ((unsigned long long)
270    __builtin_sh_media_MMACNFX_WL ((v2hi) mm_l, (v2hi) mn_l,
271				   (uv2si) mw));
272}
273
274static __inline unsigned long long
275sh_media_MMUL_L (unsigned long long mm, unsigned long long mn)
276{
277  typedef float v2si __attribute__ ((mode(V2SI)));
278
279  return (unsigned long long) __builtin_mulv2si3 ((v2si) mm, (v2si) mn);
280}
281
282static __inline unsigned long long
283sh_media_MMUL_W (unsigned long long mm, unsigned long long mn)
284{
285  typedef float v4hi __attribute__ ((mode(V4HI)));
286
287  return (unsigned long long) __builtin_mulv4hi3 ((v4hi) mm, (v4hi) mn);
288}
289
290static __inline unsigned long long
291sh_media_MMULFX_L (unsigned long long mm, unsigned long long mn)
292{
293  typedef float v2si __attribute__ ((mode(V2SI)));
294
295  return (unsigned long long) __builtin_sh_media_MMULFX_L ((v2si) mm,
296							   (v2si) mn);
297}
298
299static __inline unsigned long long
300sh_media_MMULFX_W (unsigned long long mm, unsigned long long mn)
301{
302  typedef float v4hi __attribute__ ((mode(V4HI)));
303
304  return (unsigned long long) __builtin_sh_media_MMULFX_W ((v4hi) mm,
305							   (v4hi) mn);
306}
307
308static __inline unsigned long long
309sh_media_MMULFXRP_W (unsigned long long mm, unsigned long long mn)
310{
311  typedef float v4hi __attribute__ ((mode(V4HI)));
312
313  return (unsigned long long) __builtin_sh_media_MMULFXRP_W ((v4hi) mm,
314							     (v4hi) mn);
315}
316
317static __inline unsigned long long
318sh_media_MMULHI_WL (unsigned long long mm, unsigned long long mn)
319{
320  typedef float v4hi __attribute__ ((mode(V4HI)));
321
322  return (unsigned long long) __builtin_sh_media_MMULHI_WL ((v4hi) mm,
323							    (v4hi) mn);
324}
325
326static __inline unsigned long long
327sh_media_MMULLO_WL (unsigned long long mm, unsigned long long mn)
328{
329  typedef float v4hi __attribute__ ((mode(V4HI)));
330
331  return (unsigned long long) __builtin_sh_media_MMULLO_WL ((v4hi) mm,
332							    (v4hi) mn);
333}
334
335static __inline unsigned long long
336sh_media_MMULSUM_WQ (unsigned long long mm, unsigned long long mn,
337		     unsigned long long mw)
338{
339  typedef unsigned int uv4hi __attribute__ ((mode(V4HI)));
340
341  return __builtin_sh_media_MMULSUM_WQ ((uv4hi) mm, (uv4hi) mn, mw);
342}
343
344static __inline unsigned long long
345sh_media_MPERM_W (unsigned long long mm, unsigned int mn)
346{
347  typedef float v4hi __attribute__ ((mode(V4HI)));
348
349  return (unsigned long long) __builtin_sh_media_MPERM_W ((v4hi) mm, mn);
350}
351
352static __inline unsigned long long
353sh_media_MSAD_UBQ (unsigned long long mm, unsigned long long mn,
354		   unsigned long long mw)
355{
356  typedef unsigned int uv8qi __attribute__ ((mode(V8QI)));
357
358  return __builtin_sh_media_MSAD_UBQ ((uv8qi) mm, (uv8qi) mn, mw);
359}
360
361static __inline unsigned long long
362sh_media_MSHALDS_L (unsigned long long mm, unsigned int mn)
363{
364  typedef float v2si __attribute__ ((mode(V2SI)));
365
366  return (unsigned long long) __builtin_sh_media_MSHALDS_L ((v2si) mm, mn);
367}
368
369static __inline unsigned long long
370sh_media_MSHALDS_W (unsigned long long mm, unsigned int mn)
371{
372  typedef float v4hi __attribute__ ((mode(V4HI)));
373
374  return (unsigned long long) __builtin_sh_media_MSHALDS_W ((v4hi) mm, mn);
375}
376
377static __inline unsigned long long
378sh_media_MSHARD_L (unsigned long long mm, unsigned int mn)
379{
380  typedef float v2si __attribute__ ((mode(V2SI)));
381
382  return (unsigned long long) __builtin_ashrv2si3 ((v2si) mm, mn);
383}
384
385static __inline unsigned long long
386sh_media_MSHARD_W (unsigned long long mm, unsigned int mn)
387{
388  typedef float v4hi __attribute__ ((mode(V4HI)));
389
390  return (unsigned long long) __builtin_ashrv4hi3 ((v4hi) mm, mn);
391}
392
393#define sh_media_MSHARDS_Q __builtin_sh_media_MSHARDS_Q
394
395static __inline unsigned long long
396sh_media_MSHFHI_B (unsigned long long mm, unsigned long long mn)
397{
398  typedef float v8qi __attribute__ ((mode(V8QI)));
399
400  return (unsigned long long) __builtin_sh_media_MSHFHI_B ((v8qi) mm,
401							   (v8qi) mn);
402}
403
404static __inline unsigned long long
405sh_media_MSHFHI_L (unsigned long long mm, unsigned long long mn)
406{
407  typedef float v2si __attribute__ ((mode(V2SI)));
408
409  return (unsigned long long) __builtin_sh_media_MSHFHI_L ((v2si) mm,
410							   (v2si) mn);
411}
412
413static __inline unsigned long long
414sh_media_MSHFHI_W (unsigned long long mm, unsigned long long mn)
415{
416  typedef float v4hi __attribute__ ((mode(V4HI)));
417
418  return (unsigned long long) __builtin_sh_media_MSHFHI_W ((v4hi) mm,
419							   (v4hi) mn);
420}
421
422static __inline unsigned long long
423sh_media_MSHFLO_B (unsigned long long mm, unsigned long long mn)
424{
425  typedef float v8qi __attribute__ ((mode(V8QI)));
426
427  return (unsigned long long) __builtin_sh_media_MSHFLO_B ((v8qi) mm,
428							   (v8qi) mn);
429}
430
431static __inline unsigned long long
432sh_media_MSHFLO_L (unsigned long long mm, unsigned long long mn)
433{
434  typedef float v2si __attribute__ ((mode(V2SI)));
435
436  return (unsigned long long) __builtin_sh_media_MSHFLO_L ((v2si) mm,
437							   (v2si) mn);
438}
439
440static __inline unsigned long long
441sh_media_MSHFLO_W (unsigned long long mm, unsigned long long mn)
442{
443  typedef float v4hi __attribute__ ((mode(V4HI)));
444
445  return (unsigned long long) __builtin_sh_media_MSHFLO_W ((v4hi) mm,
446							   (v4hi) mn);
447}
448
449static __inline unsigned long long
450sh_media_MSHLLD_L (unsigned long long mm, unsigned int mn)
451{
452  typedef float v2si __attribute__ ((mode(V2SI)));
453
454  return (unsigned long long) __builtin_ashlv2si3 ((v2si) mm, mn);
455}
456
457static __inline unsigned long long
458sh_media_MSHLLD_W (unsigned long long mm, unsigned int mn)
459{
460  typedef float v4hi __attribute__ ((mode(V4HI)));
461
462  return (unsigned long long) __builtin_ashlv4hi3 ((v4hi) mm, mn);
463}
464
465static __inline unsigned long long
466sh_media_MSHLRD_L (unsigned long long mm, unsigned int mn)
467{
468  typedef float v2si __attribute__ ((mode(V2SI)));
469
470  return (unsigned long long) __builtin_lshrv2si3 ((v2si) mm, mn);
471}
472
473static __inline unsigned long long
474sh_media_MSHLRD_W (unsigned long long mm, unsigned int mn)
475{
476  typedef float v4hi __attribute__ ((mode(V4HI)));
477
478  return (unsigned long long) __builtin_lshrv4hi3 ((v4hi) mm, mn);
479}
480
481static __inline unsigned long long
482sh_media_MSUB_L (unsigned long long mm, unsigned long long mn)
483{
484  typedef float v2si __attribute__ ((mode(V2SI)));
485
486  return (unsigned long long) __builtin_subv2si3 ((v2si) mm, (v2si) mn);
487}
488
489static __inline unsigned long long
490sh_media_MSUB_W (unsigned long long mm, unsigned long long mn)
491{
492  typedef float v4hi __attribute__ ((mode(V4HI)));
493
494  return (unsigned long long) __builtin_subv4hi3 ((v4hi) mm, (v4hi) mn);
495}
496
497static __inline unsigned long long
498sh_media_MSUBS_L (unsigned long long mm, unsigned long long mn)
499{
500  typedef float v2si __attribute__ ((mode(V2SI)));
501
502  return (unsigned long long) __builtin_sssubv2si3 ((v2si) mm, (v2si) mn);
503}
504
505static __inline unsigned long long
506sh_media_MSUBS_UB (unsigned long long mm, unsigned long long mn)
507{
508  typedef float v8qi __attribute__ ((mode(V8QI)));
509
510  return (unsigned long long) __builtin_ussubv8qi3 ((v8qi) mm, (v8qi) mn);
511}
512
513static __inline unsigned long long
514sh_media_MSUBS_W (unsigned long long mm, unsigned long long mn)
515{
516  typedef float v4hi __attribute__ ((mode(V4HI)));
517
518  return (unsigned long long) __builtin_sssubv4hi3 ((v4hi) mm, (v4hi) mn);
519}
520
521#if ! __SH4_NOFPU__
522/* Floating-point Intrinsics */
523
524#define sh_media_FABS_D __builtin_fabs
525#define sh_media_FABS_S __builtin_fabsf
526#define sh_media_FCMPUN_D __builtin_isunordered
527#define sh_media_FCMPUN_S __builtin_isunordered
528
529static __inline float sh_media_FCOSA_S (float fg)
530{
531  union { int i; float f; } u;
532
533  u.f = fg;
534  return __builtin_sh_media_FCOSA_S (u.i);
535}
536
537static __inline float
538sh_media_FGETSCR (void)
539{
540  float f;
541
542  __asm volatile ("fgetscr %0" : "=f" (f));
543  return f;
544}
545
546static __inline float
547sh_media_FIPR_S (const void *fvg, const void *fvh)
548{
549  typedef float v4sf __attribute__ ((mode(V4SF)));
550  v4sf vg = *(v4sf*) fvg;
551  v4sf vh = *(v4sf*) fvh;
552
553  return __builtin_sh_media_FIPR_S (vg, vh);
554}
555
556#if 0
557/* This gives different results for -O0  */
558static __inline float
559sh_media_FMAC_S (float fg, float fh, float fq)
560{
561  return fg * fh + fq;
562}
563#else
564
565#define sh_media_FMAC_S __builtin_sh_media_FMAC_S
566#endif
567
568static __inline long long
569sh_media_FMOV_DQ (double dg)
570{
571  union { long long l; double d; } u;
572
573  u.d = dg;
574  return u.l;
575}
576
577static __inline float
578sh_media_FMOV_LS (int mm)
579{
580  union { int i; float f; } u;
581
582  u.i = mm;
583  return u.f;
584}
585
586static __inline double
587sh_media_FMOV_QD (long long mm)
588{
589  union { long long l; double d; } u;
590
591  u.l = mm;
592  return u.d;
593}
594
595static __inline int
596sh_media_FMOV_SL (float fg)
597{
598  union { int i; float f; } u;
599
600  u.f = fg;
601  return u.i;
602}
603
604static __inline void
605sh_media_FPUTSCR (float fg)
606{
607  __asm volatile ("fputscr %0" : : "f" (fg));
608}
609
610static __inline float sh_media_FSINA_S (float fg)
611{
612  union { int i; float f; } u;
613
614  u.f = fg;
615  return __builtin_sh_media_FSINA_S (u.i);
616}
617
618/* Can't use __builtin_sqrt / __builtin_sqrtf because they still implement
619   error handling unless -ffast-math is used.  */
620#define sh_media_FSQRT_D __builtin_sh_media_FSQRT_D
621#define sh_media_FSQRT_S __builtin_sh_media_FSQRT_S
622#define sh_media_FSRRA_S __builtin_sh_media_FSRRA_S
623
624static __inline void
625sh_media_FTRV_S (const void *mtrxg, const void *fvh, void *fvf)
626{
627  typedef float v16sf __attribute__ ((mode(V16SF)));
628  typedef float v4sf __attribute__ ((mode(V4SF)));
629  v16sf mtrx = *(v16sf*) mtrxg;
630  v4sf vh = *(v4sf*) fvh;
631
632  *(v4sf*) fvf = __builtin_sh_media_FTRV_S (mtrx, vh);
633}
634#endif /* ! __SH4_NOFPU__ */
635
636/* Not implemented here: Control and Configuration intrinsics.  */
637/* Misaligned Access Support intrinsics */
638
639static __inline unsigned long long
640sh_media_LDHI_L (void *p, int s)
641{
642  return __builtin_sh_media_LDHI_L ((char *)p + s);
643}
644
645static __inline unsigned long long
646sh_media_LDHI_Q (void *p, int s)
647{
648  return __builtin_sh_media_LDHI_Q ((char *)p + s);
649}
650
651static __inline unsigned long long
652sh_media_LDLO_L (void *p, int s)
653{
654  return __builtin_sh_media_LDLO_L ((char *)p + s);
655}
656
657static __inline unsigned long long
658sh_media_LDLO_Q (void *p, int s)
659{
660  return __builtin_sh_media_LDLO_Q ((char *)p + s);
661}
662
663static __inline void
664sh_media_STHI_L (void *p, int s, unsigned int mw)
665{
666  __builtin_sh_media_STHI_L ((char*)p + s, mw);
667}
668
669static __inline void
670sh_media_STHI_Q (void *p, int s, unsigned long long mw)
671{
672  __builtin_sh_media_STHI_Q ((char*)p + s, mw);
673}
674
675static __inline void
676sh_media_STLO_L (void *p, int s, unsigned int mw)
677{
678  __builtin_sh_media_STLO_L ((char*)p + s, mw);
679}
680
681static __inline void
682sh_media_STLO_Q (void *p, int s, unsigned long long mw)
683{
684  __builtin_sh_media_STLO_Q ((char*)p + s, mw);
685}
686
687/* Miscellaneous intrinsics */
688
689#define sh_media_NSB __builtin_sh_media_NSB
690
691static __inline unsigned long long
692sh_media_BYTEREV (unsigned long long mm)
693{
694  typedef float v8qi __attribute__ ((mode(V8QI)));
695
696  return (unsigned long long) __builtin_sh_media_BYTEREV ((v8qi) mm);
697}
698
699__inline__ static unsigned long long
700sh_media_CMVEQ (unsigned long long mm, unsigned long long mn, unsigned long long mw) __attribute__ ((always_inline));
701
702__inline__ static unsigned long long
703sh_media_CMVEQ (unsigned long long mm, unsigned long long mn, unsigned long long mw)
704{
705  return mm == 0 ? mn : mw;
706}
707
708__inline__ static unsigned long long
709sh_media_CMVNE (unsigned long long mm, unsigned long long mn, unsigned long long mw) __attribute__ ((always_inline));
710
711__inline__ static unsigned long long
712sh_media_CMVNE (unsigned long long mm, unsigned long long mn, unsigned long long mw)
713{
714  return mm != 0 ? mn : mw;
715}
716
717static __inline long long
718sh_media_ADDZ_L (unsigned int mm, unsigned int mn)
719{
720  return mm + mn;
721}
722
723/* NOP and Synchronization intrinsics not implemented here.  */
724
725static __inline__ void sh_media_PREFO(void *mm, int s)
726{
727  __builtin_sh_media_PREFO (mm + s, 0, 0);
728}
729
730/* Event Handling intrinsics not implemented here.  */
731
732/* Old asm stuff */
733
734static __inline__
735void
736sh_media_NOP (void)
737{
738  __asm__ ("nop" : :);
739}
740
741__inline__ static
742unsigned long long
743sh_media_SWAP_Q (void *mm, long long mn, unsigned long long mw)
744{
745  unsigned long long res;
746  unsigned long long *addr = (unsigned long long *)((char *)mm + mn);
747  __asm__ ("swap.q	%m1, %0" : "=r" (res), "+o" (*addr) : "0" (mw));
748  return res;
749}
750
751__inline__ static
752void
753sh_media_SYNCI (void)
754{
755  __asm__ __volatile__ ("synci");
756}
757
758__inline__ static
759void
760sh_media_SYNCO (void)
761{
762  __asm__ __volatile__ ("synco");
763}
764
765__inline__ static
766void
767sh_media_ALLOCO (void *mm, int s)
768{
769  __builtin_sh_media_ALLOCO (mm + s);
770}
771
772__inline__ static
773void
774sh_media_ICBI (void *mm, int s)
775{
776  __asm__ __volatile__ ("icbi	%m0" : : "o" (((char*)mm)[s]));
777}
778
779__inline__ static
780void
781sh_media_OCBI (void *mm, int s)
782{
783  __asm__ __volatile__ ("ocbi	%m0" : : "o" (((char*)mm)[s]));
784}
785
786__inline__ static
787void
788sh_media_OCBP (void *mm, int s)
789{
790  __asm__ __volatile__ ("ocbp	%m0" : : "o" (((char*)mm)[s]));
791}
792
793__inline__ static
794void
795sh_media_OCBWB (void *mm, int s)
796{
797  __asm__ __volatile__ ("ocbwb	%m0" : : "o" (((char*)mm)[s]));
798}
799
800__inline__ static
801void
802sh_media_PREFI (void *mm, int s)
803{
804  __asm__ __volatile__ ("prefi	%m0" : : "o" (((char*)mm)[s]));
805}
806
807__inline__ static
808void
809sh_media_BRK (void)
810{
811  __asm__ __volatile__ ("brk");
812}
813
814__inline__ static
815void
816sh_media_TRAPA (unsigned long long mm)
817{
818  __asm__ __volatile__ ("trapa	%%0" : : "r" (mm));
819}
820
821__inline__ static
822short
823sh_media_unaligned_LD_W (void *p)
824{
825#if __LITTLE_ENDIAN__
826  return (((unsigned char *)p)[0]
827	  | (((short)((__signed__ char *)p)[1]) << 8));
828#else
829  return ((((short)((__signed__ char *)p)[0]) << 8)
830	  | ((unsigned char *)p)[1]);
831#endif
832}
833
834__inline__ static
835unsigned short
836sh_media_unaligned_LD_UW (void *p)
837{
838  unsigned char *addr = p;
839#if __LITTLE_ENDIAN__
840  return sh_media_MSHFLO_B (addr[0], addr[1]);
841#else
842  return sh_media_MSHFLO_B (addr[1], addr[0]);
843#endif
844}
845
846/* We don't use the sh_media_LD* functions here because that turned out
847   to impede constant propagation of the offsets into the ldhi / ldlo
848   instructions.  */
849__inline__ static
850int
851sh_media_unaligned_LD_L (void *p)
852{
853#if __LITTLE_ENDIAN__
854  return (__builtin_sh_media_LDHI_L ((char *)p + 3)
855	  | __builtin_sh_media_LDLO_L (p));
856#else
857  return (__builtin_sh_media_LDLO_L ((char *)p + 3)
858	  | __builtin_sh_media_LDHI_L (p));
859#endif
860}
861
862__inline__ static
863long long
864sh_media_unaligned_LD_Q (void *p)
865{
866#if __LITTLE_ENDIAN__
867  return (__builtin_sh_media_LDHI_Q ((char *)p + 7)
868	  | __builtin_sh_media_LDLO_Q (p));
869#else
870  return (__builtin_sh_media_LDLO_Q ((char *)p + 7)
871	  | __builtin_sh_media_LDHI_Q (p));
872#endif
873}
874
875__inline__ static
876void
877sh_media_unaligned_ST_W (void *p, unsigned int k)
878{
879  char *addr = p;
880#if __LITTLE_ENDIAN__
881  addr[0] = k;
882  addr[1] = k >> 8;
883#else
884  addr[1] = k;
885  addr[0] = k >> 8;
886#endif
887}
888
889/* We don't use the sh_media_ST* functions here because that turned out
890   to impede constant propagation of the offsets into the ldhi / ldlo
891   instructions.  */
892__inline__ static
893void
894sh_media_unaligned_ST_L (void *p, unsigned int k)
895{
896#if __LITTLE_ENDIAN__
897  __builtin_sh_media_STHI_L (p + 3, k);
898  __builtin_sh_media_STLO_L (p, k);
899#else
900  __builtin_sh_media_STLO_L (p + 3, k);
901  __builtin_sh_media_STHI_L (p, k);
902#endif
903}
904
905__inline__ static
906void
907sh_media_unaligned_ST_Q (void *p, unsigned long long k)
908{
909#if __LITTLE_ENDIAN__
910  __builtin_sh_media_STHI_Q (p + 7, k);
911  __builtin_sh_media_STLO_Q (p, k);
912#else
913  __builtin_sh_media_STLO_Q (p + 7, k);
914  __builtin_sh_media_STHI_Q (p, k);
915#endif
916}
917
918#if ! __SH4_NOFPU__
919__inline__ static
920void
921sh_media_FVCOPY_S (const void *fvg, void *fvf)
922{
923  const __GCC_FV *g = fvg;
924  __GCC_FV *f = fvf;
925  *f = *g;
926}
927
928__inline__ static
929void
930sh_media_FVADD_S (const void *fvg, const void *fvh, void *fvf)
931{
932  const float *g = fvg, *h = fvh;
933  float *f = fvf;
934#if 1
935  int i;
936
937  for (i = 0; i < 4; i++)
938    f[i] = g[i] + h[i];
939#else
940  f[0] = g[0] + h[0];
941  f[1] = g[1] + h[1];
942  f[2] = g[2] + h[2];
943  f[3] = g[3] + h[3];
944#endif
945}
946
947__inline__ static
948void
949sh_media_FVSUB_S (const void *fvg, const void *fvh, void *fvf)
950{
951  const float *g = fvg, *h = fvh;
952  float *f = fvf;
953#if 1
954  int i;
955
956  for (i = 0; i < 4; i++)
957    f[i] = g[i] - h[i];
958#else
959  f[0] = g[0] - h[0];
960  f[1] = g[1] - h[1];
961  f[2] = g[2] - h[2];
962  f[3] = g[3] - h[3];
963#endif
964}
965
966__inline__ static
967void
968sh_media_FMTRXCOPY_S (const void *mtrxg, void *mtrxf)
969{
970  const __GCC_MTRX *g = mtrxg;
971  __GCC_MTRX *f = mtrxf;
972  *f = *g;
973}
974
975__inline__ static
976void
977sh_media_FMTRXADD_S (const void *mtrxg, const void *mtrxh, void *mtrxf)
978{
979  const __GCC_FV *g = mtrxg, *h = mtrxh;
980  __GCC_FV *f = mtrxf;
981#if 1
982  int i;
983
984  for (i = 0; i < 4; i++)
985    sh_media_FVADD_S (&g[i], &h[i], &f[i]);
986#else
987  sh_media_FVADD_S (&g[0], &h[0], &f[0]);
988  sh_media_FVADD_S (&g[1], &h[1], &f[1]);
989  sh_media_FVADD_S (&g[2], &h[2], &f[2]);
990  sh_media_FVADD_S (&g[3], &h[3], &f[3]);
991#endif
992}
993
994__inline__ static
995void
996sh_media_FMTRXSUB_S (const void *mtrxg, const void *mtrxh, void *mtrxf)
997{
998  const __GCC_FV *g = mtrxg, *h = mtrxh;
999  __GCC_FV *f = mtrxf;
1000#if 1
1001  int i;
1002
1003  for (i = 0; i < 4; i++)
1004    sh_media_FVSUB_S (&g[i], &h[i], &f[i]);
1005#else
1006  sh_media_FVSUB_S (&g[0], &h[0], &f[0]);
1007  sh_media_FVSUB_S (&g[1], &h[1], &f[1]);
1008  sh_media_FVSUB_S (&g[2], &h[2], &f[2]);
1009  sh_media_FVSUB_S (&g[3], &h[3], &f[3]);
1010#endif
1011}
1012
1013__inline__ static
1014void
1015sh_media_FTRVADD_S (const void *mtrxg, const void *fvh, const void *fvi, void *fvf)
1016{
1017  sh_media_FTRV_S (mtrxg, fvh, fvf);
1018  sh_media_FVADD_S (fvf, fvi, fvf);
1019}
1020
1021__inline__ static
1022void
1023sh_media_FTRVSUB_S (const void *mtrxg, const void *fvh, const void *fvi, void *fvf)
1024{
1025  sh_media_FTRV_S (mtrxg, fvh, fvf);
1026  sh_media_FVSUB_S (fvf, fvi, fvf);
1027}
1028
1029__inline__ static
1030void
1031sh_media_FMTRXMUL_S (const void *mtrxg, const void *mtrxh, void *mtrxf)
1032{
1033  const __GCC_FV *g = mtrxg;
1034  __GCC_FV *f = mtrxf;
1035#if 1
1036  int j;
1037
1038  for (j = 0; j < 4; j++)
1039    sh_media_FTRV_S (mtrxh, &g[j], &f[j]);
1040#else
1041  sh_media_FTRV_S (mtrxh, &g[0], &f[0]);
1042  sh_media_FTRV_S (mtrxh, &g[1], &f[1]);
1043  sh_media_FTRV_S (mtrxh, &g[2], &f[2]);
1044  sh_media_FTRV_S (mtrxh, &g[3], &f[3]);
1045#endif
1046}
1047
1048__inline__ static
1049void
1050sh_media_FMTRXMULADD_S (const void *mtrxg, const void *mtrxh, const void *mtrxi, void *mtrxf)
1051{
1052  const __GCC_FV *g = mtrxg, *i = mtrxi;
1053  __GCC_FV *f = mtrxf;
1054#if 1
1055  int j;
1056
1057  for (j = 0; j < 4; j++)
1058    sh_media_FTRVADD_S (mtrxh, &g[j], &i[j], &f[j]);
1059#else
1060  sh_media_FTRVADD_S (mtrxh, &g[0], &i[0], &f[0]);
1061  sh_media_FTRVADD_S (mtrxh, &g[1], &i[1], &f[1]);
1062  sh_media_FTRVADD_S (mtrxh, &g[2], &i[2], &f[2]);
1063  sh_media_FTRVADD_S (mtrxh, &g[3], &i[3], &f[3]);
1064#endif
1065}
1066
1067__inline__ static
1068void
1069sh_media_FMTRXMULSUB_S (const void *mtrxg, const void *mtrxh, const void *mtrxi, void *mtrxf)
1070{
1071  const __GCC_FV *g = mtrxg, *i = mtrxi;
1072  __GCC_FV *f = mtrxf;
1073#if 1
1074  int j;
1075
1076  for (j = 0; j < 4; j++)
1077    sh_media_FTRVSUB_S (mtrxh, &g[j], &i[j], &f[j]);
1078#else
1079  sh_media_FTRVSUB_S (mtrxh, &g[0], &i[0], &f[0]);
1080  sh_media_FTRVSUB_S (mtrxh, &g[1], &i[1], &f[1]);
1081  sh_media_FTRVSUB_S (mtrxh, &g[2], &i[2], &f[2]);
1082  sh_media_FTRVSUB_S (mtrxh, &g[3], &i[3], &f[3]);
1083#endif
1084}
1085#endif /* ! __SH4_NOFPU__ */
1086
1087#endif /* __SHMEDIA__ */
1088
1089#endif /* _USHMEDIA_H */
1090