Subversion Repositories eduke32

Rev

Rev 3177 | Rev 3496 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 Plagman 1
// Function-wrapped Watcom pragmas
2456 hendricks2 2
// by Jonathon Fowler (jf@jonof.id.au)
5 Plagman 3
//
4
// These functions represent some of the more longer-winded pragmas
5
// from the original pragmas.h wrapped into functions for easier
6
// use since many jumps and whatnot make it harder to write macro-
7
// inline versions. I'll eventually convert these to macro-inline
8
// equivalents.         --Jonathon
9
 
10
//#include "pragmas.h"
11
#include "compat.h"
12
 
1205 terminx 13
int32_t dmval;
5 Plagman 14
 
2621 helixhorne 15
#if defined(__GNUC__) && defined(GEKKO)
5 Plagman 16
 
2621 helixhorne 17
// naked function (no prolog/epilog)
18
int32_t scale(int32_t a, int32_t d, int32_t c)
19
{
20
//      return ((int64_t)a * d) / c;
21
 
22
        __asm__ __volatile__ (
23
                " mullw   6, 3, 4\n"
24
                " mulhw   4, 3, 4\n"
25
                " mr      3, 6\n"
26
 
27
                " srawi.  0, 5, 31\n"
28
                " cmpwi cr1, 4, 0\n"
29
                " crxor   7, 0, 4\n"
30
 
31
                " xor     5, 0, 5\n"
32
                " subf.   5, 0, 5\n"
33
 
34
                " beq     DivByZero\n"
35
                " bge   cr1, Div64Common\n"
36
 
37
                " subfic  3, 3, 0\n"
38
                " subfze  4, 4\n"
39
 
40
                "Div64Common:\n"
41
                " cmplw   4, 5\n"
42
 
43
                " cntlzw  6, 5\n"
44
                " xor     4, 4, 3\n"
45
                " slw     5, 5, 6\n"
46
                " rotlw   4, 4, 6\n"
47
                " slw     3, 3, 6\n"
48
                " li      7, 2\n"
49
                " xor     4, 4, 3\n"
50
 
51
                " bge DivOverflow\n"
52
                " mtctr   7\n"
53
 
54
                "Div64Compute:\n"
55
                " srwi    6, 5, 16\n"
56
                " divwu   7, 4, 6\n"
57
                " mullw   6, 7, 6\n"
58
                " subf    4, 6, 4\n"
59
                " slwi    4, 4, 16\n"
60
                " inslwi  4, 3, 16, 16\n"
61
                " slwi    3, 3, 16\n"
62
                " clrlwi  6, 5, 16\n"
63
                " mullw   6, 7, 6\n"
64
                " subfc   4, 6, 4\n"
65
                " subfe.  6, 6, 6\n"
66
                " add     3, 3, 7\n"
67
                " bge Div64Done\n"
68
                "Div64Correct:\n"
69
                " addc    4, 4, 5\n"
70
                " addze.  6, 6\n"
71
                " subi    3, 3, 1\n"
72
                " blt     Div64Correct\n"
73
 
74
                "Div64Done:\n"
75
                " bdnz    Div64Compute\n"
76
 
77
                " cmpwi   3, 0\n"
78
                " bso   cr1, Div64QuotientNeg\n"
79
 
80
                " blt     DivOverflow\n"
81
                " blr\n"
82
 
83
                "Div64QuotientNeg:\n"
84
                " neg.    3, 3\n"
85
                " blelr\n"
86
 
87
                "DivOverflow:\n"
88
                " cror    4, 7, 7\n"
89
 
90
                "DivByZero:\n"
91
                " lis     3, 0x8000\n"
92
                " bltlr cr1\n"
93
                " subi    3, 3, 1\n"
94
                " blr\n"
95
        );
96
}
97
 
98
void clearbufbyte(void *d, int32_t c, int32_t a)
99
{
100
        if (a==0) {
101
                uint8_t *dd = (uint8_t*)d;
102
                int32_t align = (32 - (int32_t)d) & 31;
103
 
104
                if (align && c >= align) {
105
                        uint32_t izero = 0;
106
                        double fzero = 0;
107
                        c -= align;
108
 
109
                        if (align&1) {
110
                                *dd = izero;
111
                                dd += 1;
112
                        }
113
                        if (align&2) {
114
                                *(uint16_t*)dd = izero;
115
                                dd += 2;
116
                        }
117
                        if (align&4) {
118
                                *(uint32_t*)dd = izero;
119
                                dd += 4;
120
                        }
121
                        if (align&8) {
122
                                *(double*)dd = fzero;
123
                                dd += 8;
124
                        }
125
                        if (align&16) {
126
                                *(double*)dd = fzero;
127
                                *(double*)(dd+8) = fzero;
128
                                dd += 16;
129
                        }
130
                }
131
                align = c >> 5;
132
                while (align) {
133
                        __asm__ (
134
                                " dcbz  0, %0\n"
135
                                " addi %0, %0, 32\n"
136
                                : "+r"(dd)
137
                                :
138
                                : "memory"
139
                        );
140
                        align--;
141
                }
142
                if ((c &= 31)) {
143
                        while (c--) {
144
                                *dd++ = 0;
145
                        }
146
                }
147
                return;
148
        }
149
        __asm__ __volatile__ (
150
                " add    %1, %1, %2\n"
151
                " neg.   %2, %2\n"
152
                " beq 2f\n"
153
                "1:\n"
154
                " stbx   %0, %1, %2\n"
155
                " addic. %2, %2, 1\n"
156
                " rotrwi %0, %0, 8\n"
157
                " bne 1b\n"
158
                "2:\n"
159
                : "+r"(a), "+b"(d), "+r"(c)
160
                :
161
                : "cc", "xer", "memory"
162
        );
163
}
164
 
165
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM) // NOASM
166
 
5 Plagman 167
//
168
// GCC Inline Assembler version
169
//
170
 
171
#define ASM __asm__ __volatile__
172
 
173
 
1205 terminx 174
int32_t boundmulscale(int32_t a, int32_t b, int32_t c)
5 Plagman 175
{
584 terminx 176
    ASM(
109 terminx 177
        "imull %%ebx\n\t"
178
        "movl %%edx, %%ebx\n\t"         // mov ebx, edx
179
        "shrdl %%cl, %%edx, %%eax\n\t"  // mov eax, edx, cl
180
        "sarl %%cl, %%edx\n\t"          // sar edx, cl
181
        "xorl %%eax, %%edx\n\t"         // xor edx, eax
182
        "js 0f\n\t"                     // js checkit
183
        "xorl %%eax, %%edx\n\t"         // xor edx, eax
184
        "jz 1f\n\t"                     // js skipboundit
185
        "cmpl $0xffffffff, %%edx\n\t"   // cmp edx, 0xffffffff
186
        "je 1f\n\t"                     // je skipboundit
187
        "0:\n\t"                        // checkit:
188
        "movl %%ebx, %%eax\n\t"         // mov eax, ebx
189
        "sarl $31, %%eax\n\t"           // sar eax, 31
190
        "xorl $0x7fffffff, %%eax\n\t"   // xor eax, 0x7fffffff
191
        "1:"                            // skipboundit:
584 terminx 192
    : "+a"(a), "+b"(b), "+c"(c) // input eax ebx ecx
1762 terminx 193
            :
194
            : "edx", "cc"
195
        );
109 terminx 196
    return a;
5 Plagman 197
}
198
 
199
 
1205 terminx 200
void clearbufbyte(void *D, int32_t c, int32_t a)
5 Plagman 201
{
584 terminx 202
    ASM(
109 terminx 203
        "cmpl $4, %%ecx\n\t"
204
        "jae 1f\n\t"
205
        "testb $1, %%cl\n\t"
206
        "jz 0f\n\t"                     // jz preskip
207
        "stosb\n\t"
208
        "0:\n\t"                        // preskip:
209
        "shrl $1, %%ecx\n\t"
210
        "rep\n\t"
211
        "stosw\n\t"
212
        "jmp 5f\n\t"                    // jmp endit
213
        "1:\n\t"                        // intcopy:
214
        "testl $1, %%edi\n\t"
215
        "jz 2f\n\t"                     // jz skip1
216
        "stosb\n\t"
217
        "decl %%ecx\n\t"
218
        "2:\n\t"                        // skip1:
219
        "testl $2, %%edi\n\t"
220
        "jz 3f\n\t"                     // jz skip2
221
        "stosw\n\t"
222
        "subl $2, %%ecx\n\t"
223
        "3:\n\t"                        // skip2:
224
        "movl %%ecx, %%ebx\n\t"
225
        "shrl $2, %%ecx\n\t"
226
        "rep\n\t"
227
        "stosl\n\t"
228
        "testb $2, %%bl\n\t"
229
        "jz 4f\n\t"                     // jz skip3
230
        "stosw\n\t"
231
        "4:\n\t"                        // skip3:
232
        "testb $1, %%bl\n\t"
233
        "jz 5f\n\t"                     // jz endit
234
        "stosb\n\t"
235
        "5:"                            // endit
584 terminx 236
    : "+D"(D), "+c"(c), "+a"(a) :
1762 terminx 237
            : "ebx", "memory", "cc"
238
        );
5 Plagman 239
}
240
 
2361 helixhorne 241
void copybufbyte(const void *S, void *D, int32_t c)
5 Plagman 242
{
584 terminx 243
    ASM(
109 terminx 244
        "cmpl $4, %%ecx\n\t"            // cmp ecx, 4
245
        "jae 1f\n\t"
246
        "testb $1, %%cl\n\t"            // test cl, 1
247
        "jz 0f\n\t"
248
        "movsb\n\t"
249
        "0:\n\t"                        // preskip:
250
        "shrl $1, %%ecx\n\t"            // shr ecx, 1
251
        "rep\n\t"
252
        "movsw\n\t"
253
        "jmp 5f\n\t"
254
        "1:\n\t"                        // intcopy:
255
        "testl $1, %%edi\n\t"           // test edi, 1
256
        "jz 2f\n\t"
257
        "movsb\n\t"
258
        "decl %%ecx\n\t"
259
        "2:\n\t"                        // skip1:
260
        "testl $2, %%edi\n\t"           // test edi, 2
261
        "jz 3f\n\t"
262
        "movsw\n\t"
263
        "subl $2, %%ecx\n\t"            // sub ecx, 2
264
        "3:\n\t"                        // skip2:
265
        "movl %%ecx, %%ebx\n\t"         // mov ebx, ecx
266
        "shrl $2, %%ecx\n\t"            // shr ecx ,2
267
        "rep\n\t"
268
        "movsl\n\t"
269
        "testb $2, %%bl\n\t"            // test bl, 2
270
        "jz 4f\n\t"
271
        "movsw\n\t"
272
        "4:\n\t"                        // skip3:
273
        "testb $1, %%bl\n\t"            // test bl, 1
274
        "jz 5f\n\t"
275
        "movsb\n\t"
276
        "5:"                            // endit:
584 terminx 277
    : "+c"(c), "+S"(S), "+D"(D) :
1762 terminx 278
            : "ebx", "memory", "cc"
279
        );
5 Plagman 280
}
281
 
2361 helixhorne 282
void copybufreverse(const void *S, void *D, int32_t c)
5 Plagman 283
{
584 terminx 284
    ASM(
109 terminx 285
        "shrl $1, %%ecx\n\t"
286
        "jnc 0f\n\t"            // jnc skipit1
287
        "movb (%%esi), %%al\n\t"
288
        "decl %%esi\n\t"
289
        "movb %%al, (%%edi)\n\t"
290
        "incl %%edi\n\t"
291
        "0:\n\t"                // skipit1:
292
        "shrl $1, %%ecx\n\t"
293
        "jnc 1f\n\t"            // jnc skipit2
294
        "movw -1(%%esi), %%ax\n\t"
295
        "subl $2, %%esi\n\t"
296
        "rorw $8, %%ax\n\t"
297
        "movw %%ax, (%%edi)\n\t"
298
        "addl $2, %%edi\n\t"
299
        "1:\n\t"                // skipit2
300
        "testl %%ecx, %%ecx\n\t"
301
        "jz 3f\n\t"             // jz endloop
302
        "2:\n\t"                // begloop
303
        "movl -3(%%esi), %%eax\n\t"
304
        "subl $4, %%esi\n\t"
305
        "bswapl %%eax\n\t"
306
        "movl %%eax, (%%edi)\n\t"
307
        "addl $4, %%edi\n\t"
308
        "decl %%ecx\n\t"
309
        "jnz 2b\n\t"            // jnz begloop
310
        "3:"
584 terminx 311
    : "+S"(S), "+D"(D), "+c"(c) :
1762 terminx 312
            : "eax", "memory", "cc"
313
        );
5 Plagman 314
}
315
 
1454 terminx 316
#elif defined(_MSC_VER) && !defined(NOASM)              // __GNUC__ && __i386__
5 Plagman 317
 
318
//
319
// Microsoft C Inline Assembler version
320
//
321
 
322
#else                           // _MSC_VER
323
 
194 terminx 324
//
325
// Generic C version
326
//
5 Plagman 327
 
1205 terminx 328
void qinterpolatedown16(intptr_t bufptr, int32_t num, int32_t val, int32_t add)
584 terminx 329
{
330
    // gee, I wonder who could have provided this...
1205 terminx 331
    int32_t i, *lptr = (int32_t *)bufptr;
1229 terminx 332
    for (i=0; i<num; i++) { lptr[i] = (val>>16); val += add; }
194 terminx 333
}
334
 
1205 terminx 335
void qinterpolatedown16short(intptr_t bufptr, int32_t num, int32_t val, int32_t add)
584 terminx 336
{
337
    // ...maybe the same person who provided this too?
1205 terminx 338
    int32_t i; int16_t *sptr = (int16_t *)bufptr;
1229 terminx 339
    for (i=0; i<num; i++) { sptr[i] = (int16_t)(val>>16); val += add; }
194 terminx 340
}
341
 
1205 terminx 342
void clearbuf(void *d, int32_t c, int32_t a)
194 terminx 343
{
3177 helixhorne 344
    int32_t *p = (int32_t *)d;
2361 helixhorne 345
 
194 terminx 346
    while ((c--) > 0) *(p++) = a;
347
}
348
 
2361 helixhorne 349
void copybuf(const void *s, void *d, int32_t c)
194 terminx 350
{
3177 helixhorne 351
    const int32_t *p = (const int32_t *)s;
2361 helixhorne 352
    int32_t *q = (int32_t *)d;
353
 
194 terminx 354
    while ((c--) > 0) *(q++) = *(p++);
355
}
356
 
1205 terminx 357
void swapbuf4(void *a, void *b, int32_t c)
194 terminx 358
{
1762 terminx 359
    int32_t *p = (int32_t *)a, *q = (int32_t *)b;
1205 terminx 360
    int32_t x, y;
584 terminx 361
    while ((c--) > 0)
362
    {
194 terminx 363
        x = *q;
364
        y = *p;
365
        *(q++) = y;
366
        *(p++) = x;
367
    }
368
}
369
 
1205 terminx 370
void clearbufbyte(void *D, int32_t c, int32_t a)
584 terminx 371
{
372
    // Cringe City
1762 terminx 373
    char *p = (char *)D;
3178 helixhorne 374
    int32_t m[4] = { 0xffl,0xff00l,0xff0000l,(int32_t)0xff000000l };
1205 terminx 375
    int32_t n[4] = { 0,8,16,24 };
376
    int32_t z=0;
584 terminx 377
    while ((c--) > 0)
378
    {
1205 terminx 379
        *(p++) = (uint8_t)((a & m[z])>>n[z]);
194 terminx 380
        z=(z+1)&3;
381
    }
382
}
383
 
2361 helixhorne 384
void copybufbyte(const void *S, void *D, int32_t c)
194 terminx 385
{
3177 helixhorne 386
    const char *p = (const char *)S;
387
    char *q = (char *)D;
2361 helixhorne 388
 
331 terminx 389
    while ((c--) > 0) *(q++) = *(p++);
194 terminx 390
}
391
 
2361 helixhorne 392
void copybufreverse(const void *S, void *D, int32_t c)
194 terminx 393
{
3177 helixhorne 394
    const char *p = (const char *)S;
395
    char *q = (char *)D;
2361 helixhorne 396
 
331 terminx 397
    while ((c--) > 0) *(q++) = *(p--);
194 terminx 398
}
399
 
5 Plagman 400
#endif
401
 
402