Merged eb/gcell-wip2 rev 10130:10152 into trunk.
[debian/gnuradio] / gcell / include / gcell / spu / gc_spu_macs.h
diff --git a/gcell/include/gcell/spu/gc_spu_macs.h b/gcell/include/gcell/spu/gc_spu_macs.h
new file mode 100644 (file)
index 0000000..0d7dc99
--- /dev/null
@@ -0,0 +1,380 @@
+/* -*- asm -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_SPU_MACS_H
+#define INCLUDED_GC_SPU_MACS_H
+
+/*
+ * This file contains a set of macros that are generally useful when
+ * coding in SPU assembler
+ *
+ * Note that the multi-instruction macros in here may overwrite
+ * registers 77, 78, and 79 without warning.
+ */
+
+/*
+ * defines for all registers
+ */
+#define r0     $0
+#define r1     $1
+#define r2     $2
+#define r3     $3
+#define r4     $4
+#define r5     $5
+#define r6     $6
+#define r7     $7
+#define r8     $8
+#define r9     $9
+#define r10    $10
+#define r11    $11
+#define r12    $12
+#define r13    $13
+#define r14    $14
+#define r15    $15
+#define r16    $16
+#define r17    $17
+#define r18    $18
+#define r19    $19
+#define r20    $20
+#define r21    $21
+#define r22    $22
+#define r23    $23
+#define r24    $24
+#define r25    $25
+#define r26    $26
+#define r27    $27
+#define r28    $28
+#define r29    $29
+#define r30    $30
+#define r31    $31
+#define r32    $32
+#define r33    $33
+#define r34    $34
+#define r35    $35
+#define r36    $36
+#define r37    $37
+#define r38    $38
+#define r39    $39
+#define r40    $40
+#define r41    $41
+#define r42    $42
+#define r43    $43
+#define r44    $44
+#define r45    $45
+#define r46    $46
+#define r47    $47
+#define r48    $48
+#define r49    $49
+#define r50    $50
+#define r51    $51
+#define r52    $52
+#define r53    $53
+#define r54    $54
+#define r55    $55
+#define r56    $56
+#define r57    $57
+#define r58    $58
+#define r59    $59
+#define r60    $60
+#define r61    $61
+#define r62    $62
+#define r63    $63
+#define r64    $64
+#define r65    $65
+#define r66    $66
+#define r67    $67
+#define r68    $68
+#define r69    $69
+#define r70    $70
+#define r71    $71
+#define r72    $72
+#define r73    $73
+#define r74    $74
+#define r75    $75
+#define r76    $76
+#define r77    $77
+#define r78    $78
+#define r79    $79
+#define r80    $80
+#define r81    $81
+#define r82    $82
+#define r83    $83
+#define r84    $84
+#define r85    $85
+#define r86    $86
+#define r87    $87
+#define r88    $88
+#define r89    $89
+#define r90    $90
+#define r91    $91
+#define r92    $92
+#define r93    $93
+#define r94    $94
+#define r95    $95
+#define r96    $96
+#define r97    $97
+#define r98    $98
+#define r99    $99
+#define r100   $100
+#define r101   $101
+#define r102   $102
+#define r103   $103
+#define r104   $104
+#define r105   $105
+#define r106   $106
+#define r107   $107
+#define r108   $108
+#define r109   $109
+#define r110   $110
+#define r111   $111
+#define r112   $112
+#define r113   $113
+#define r114   $114
+#define r115   $115
+#define r116   $116
+#define r117   $117
+#define r118   $118
+#define r119   $119
+#define r120   $120
+#define r121   $121
+#define r122   $122
+#define r123   $123
+#define r124   $124
+#define r125   $125
+#define r126   $126
+#define r127   $127
+
+
+#define        lr      r0      // link register
+#define        sp      r1      // stack pointer
+                        // r2 is environment pointer for langs that need it (ALGOL)
+
+#define        retval  r3      // return values are passed in regs starting at r3
+
+#define        arg1    r3      // args are passed in regs starting at r3
+#define        arg2    r4
+#define        arg3    r5
+#define        arg4    r6
+#define        arg5    r7
+#define        arg6    r8
+#define        arg7    r9
+#define        arg8    r10
+#define        arg9    r11
+#define        arg10   r12
+
+//  r3 -  r74 are volatile (caller saves)
+// r74 -  r79 are volatile (scratch regs possibly destroyed by fct prolog/epilog)
+// r80 - r127 are non-volatile (callee-saves)
+
+// scratch registers reserved for use by the macros in this file.
+
+#define _gc_t0 r79
+#define        _gc_t1  r78
+#define        _gc_t2  r77
+
+/*
+ * ----------------------------------------------------------------
+ *                         pseudo ops
+ * ----------------------------------------------------------------
+ */
+#define PROC_ENTRY(name)               \
+        .text;                         \
+       .p2align 4;                     \
+       .global name;                   \
+       .type   name, @function;        \
+name:
+
+/*
+ * ----------------------------------------------------------------
+ *                 aliases for common operations
+ * ----------------------------------------------------------------
+ */
+
+// Move register (even pipe, 2 cycles)
+#define MR(rt, ra)                     or      rt, ra, ra;
+
+// Move register (odd pipe, 4 cycles)
+#define        LMR(rt, ra)                     rotqbyi rt, ra, 0;
+
+// return
+#define        RETURN()                        bi      lr;
+
+// hint for a return
+#define        HINT_RETURN(ret_label)          hbr     ret_label, lr;
+
+// return if zero
+#define BRZ_RETURN(rt)                 biz     rt, lr;
+
+// return if not zero
+#define BRNZ_RETURN(rt)                        binz    rt, lr;
+
+// return if halfword zero
+#define        BRHZ_RETURN(rt)                 bihz    rt, lr;
+
+// return if halfword not zero
+#define BRHNZ_RETURN(rt)               bihnz   rt, lr;
+
+
+/*
+ * ----------------------------------------------------------------
+ * modulo like things for constant moduli that are powers of 2
+ * ----------------------------------------------------------------
+ */
+
+// rt = ra & (pow2 - 1)
+#define MODULO(rt, ra, pow2) \
+       andi    rt, ra, (pow2)-1;
+
+// rt = pow2 - (ra & (pow2 - 1))
+#define MODULO_NEG(rt, ra, pow2) \
+       andi    rt, ra, (pow2)-1;               \
+       sfi     rt, rt, (pow2);
+
+// rt = ra & -(pow2)
+#define        ROUND_DOWN(rt, ra, pow2) \
+       andi    rt, ra, -(pow2);
+
+// rt = (ra + (pow2 - 1)) & -(pow2)
+#define ROUND_UP(rt, ra, pow2) \
+       ai      rt, ra, (pow2)-1;               \
+       andi    rt, rt, -(pow2);
+
+/*
+ * ----------------------------------------------------------------
+ * Splat - replicate a particular slot into all slots
+ * Altivec analogs...
+ * ----------------------------------------------------------------
+ */
+
+// replicate byte from slot s [0,15]
+#define VSPLTB(rt, ra, s) \
+       ilh     _gc_t0, (s)*0x0101;             \
+       shufb   rt, ra, ra, _gc_t0;
+
+// replicate halfword from slot s [0,7]
+#define        VSPLTH(rt, ra, s) \
+       ilh     _gc_t0, 2*(s)*0x0101 + 0x0001;  \
+       shufb   rt, ra, ra, _gc_t0;
+
+// replicate word from slot s [0,3]
+#define VSPLTW(rt, ra, s) \
+       iluh    _gc_t0, 4*(s)*0x0101 + 0x0001;  \
+       iohl    _gc_t0, 4*(s)*0x0101 + 0x0203;  \
+       shufb   rt, ra, ra, _gc_t0;
+       
+// replicate double from slot s [0,1]
+#define        VSPLTD(rt, ra, s) \
+       /* sp is always 16-byte aligned */ \
+       cdd     _gc_t0, 8(sp);          /* 0x10111213 14151617 00010203 04050607 */ \
+       rotqbyi rt, ra, ra, (s) << 3;   /* rotate double into preferred slot     */ \
+       shufb   rt, rt, rt, _gc_t0;
+
+/*
+ * ----------------------------------------------------------------
+ * lots of min/max variations...
+ *
+ * On a slot by slot basis, compute the min or max
+ *
+ * U - unsigned, else signed
+ * B,H,{} - byte, halfword, word
+ * F float
+ * ----------------------------------------------------------------
+ */
+
+#define MIN_SELB(rt, ra, rb, rc)       selb    rt, ra, rb, rc;
+#define MAX_SELB(rt, ra, rb, rc)       selb    rt, rb, ra, rc;
+       
+       // words
+
+#define MIN(rt, ra, rb) \
+       cgt     _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        MAX(rt, ra, rb) \
+       cgt     _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+#define UMIN(rt, ra, rb) \
+       clgt    _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        UMAX(rt, ra, rb) \
+       clgt    _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+       // bytes
+       
+#define MINB(rt, ra, rb) \
+       cgtb    _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        MAXB(rt, ra, rb) \
+       cgtb    _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+#define UMINB(rt, ra, rb) \
+       clgtb   _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        UMAXB(rt, ra, rb) \
+       clgtb   _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+       // halfwords
+       
+#define MINH(rt, ra, rb) \
+       cgth    _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        MAXH(rt, ra, rb) \
+       cgth    _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+#define UMINH(rt, ra, rb) \
+       clgth   _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        UMAXH(rt, ra, rb) \
+       clgth   _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+       // floats
+       
+#define FMIN(rt, ra, rb) \
+       fcgt    _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+#define        FMAX(rt, ra, rb) \
+       fcgt    _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+// Ignoring the sign, select the values with the minimum magnitude
+#define FMINMAG(rt, ra, rb) \
+       fcmgt   _gc_t0, ra, rb; \
+       MIN_SELB(rt, ra, rb, _gc_t0)
+       
+// Ignoring the sign, select the values with the maximum magnitude
+#define        FMAXMAG(rt, ra, rb) \
+       fcmgt   _gc_t0, ra, rb; \
+       MAX_SELB(rt, ra, rb, _gc_t0)
+
+
+#endif /* INCLUDED_GC_SPU_MACS_H */