?? intrin.c
字號:
#include "c.h"
enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };
typedef struct tagIntrinsics {
char *Name;
short NrOfArgs;
short Flags;
void (*fn)(Node p);
Symbol (*argsFn)(Node p);
} INTRINSICS;
//static Symbol Arg0,Arg1;
static Node ArgumentsTab[10];
static int ArgumentsNts[10];
static int ArgumentsIndex;
static int labelIdx=1;
extern unsigned (*emitter)(Node, int);
extern Symbol intreg[];
static void fsincos(Node p)
{
if (p->x.nestedCall) {
print("\tfldl\t(%%esp)\n\tfsincos\n\taddl\t$8,%%esp\n\tpop\t%%eax\n");
print("\tfstpl\t(%%eax");
}
else {
print("\tfsincos\n\tfstpl\t(%%eax");
}
print(")\n");
}
static void bswap(Node p) { print("\tbswap\t%%eax\n"); }
static void carry(Node p) { print("\tsbb\t%%eax,%%eax\n"); }
static void bsf(Node p) { print("\tbsf\t%%eax,%%eax\n"); }
static void bsr(Node p) { print("\tbsr\t%%eax,%%eax\n"); }
static Symbol bswapArgs(Node p)
{
return intreg[EAX];
}
static void fistp(Node p)
{
print("\tpushl\t%%eax\n");
print("\tfistps\t(%%esp)\n\tpopl\t%%eax\n");
}
static void fbld(Node p)
{
print("\tfbld\t(%%eax)\n");
}
static void Fabs(Node p) { print("\tfabs\n"); }
static void fldpi(Node p) { print("\tfldpi\n"); }
static void fldl2e(Node p) { print("\tfldl2e\n");}
static void fldlg2(Node p) { print("\tfldlg2\n");}
static void fldln2(Node p) { print("\tfldln2\n");}
static void f2xm1(Node p) { print("\tf2xm1\n"); }
static void popNestedCall(Node p)
{
if (p->x.nestedCall) {
print("\tpopl\t%%eax\n\tpopl\t%%edx\n\tpopl\t%%ecx\n");
}
}
static void mmxVectCallN(Node p,char *op,int negate)
{
popNestedCall(p);
print("\torl\t%%ecx,%%ecx\n\tje\t_$LM%d\n",labelIdx+1);
if (negate) {
print("\tpcmpeqb\t%%mm2,%%mm2\n");
}
print("_$LM%d:\n",labelIdx);
print("\tdecl\t%%ecx\n");
print("\tmovq\t(%%edx,%%ecx,8),%%mm0\n");
if (op) {
print("\t");
outs(op);
print("\t(%%eax,%%ecx,8),%%mm0\n");
if (negate) {
print("\tpxor\t%%mm2,%%mm0\n");
}
}
print("\tmovq\t%%mm0,(%%eax,%%ecx,8)\n");
print("\tjne\t_$LM%d\n",labelIdx);
print("_$LM%d:\n",labelIdx+1);
labelIdx += 2;
}
static void mmxVectCall(Node p,char *op)
{
mmxVectCallN(p,op,0);
}
static void rdtsc(Node p)
{
print("\trdtsc\n");
}
static void mmxImmCallN(Node p,char *op,int negate)
{
popNestedCall(p);
print("\torl\t%%ecx,%%ecx\n\tje\t_$LM%d\n",labelIdx+1);
print("\tmovq\t(%%edx),%%mm1\n");
if (negate) {
print("\tpcmpeqb\t%%mm2,%%mm2\n");
}
print("_$LM%d:\n",labelIdx);
print("\tdecl\t%%ecx\n");
print("\tmovq\t%%mm1,%%mm0\n\t");
outs(op);
print("\t(%%eax,%%ecx,8),%%mm0\n");
if (negate) {
print("\tpxor\t%%mm2,%%mm0\n");
}
print("\tmovq\t%%mm0,(%%eax,%%ecx,8)\n");
print("\tjne\t_$LM%d\n",labelIdx);
print("_$LM%d:\n",labelIdx+1);
labelIdx += 2;
}
static void mmxDotProd(Node p)
{
popNestedCall(p);
print("\tpxor\t%%mm7,%%mm7\n");
print("_$LM%d:\n",labelIdx);
print("\tmovq\t(%%eax),%%mm0\n");
print("\tmovq\t(%%edx),%%mm1\n");
print("\taddl\t$8,%%eax\n");
print("\tpmaddwd\t%%mm1,%%mm0\n");
print("\taddl\t$8,%%edx\n");
print("\tpaddd\t%%mm0,%%mm7\n");
print("\tdecl\t%%ecx\n");
print("\tjne\t_$LM%d\n",labelIdx);
labelIdx++;
print("\tmovq\t%%mm7,%%mm0\n");
print("\tpsrlq\t$32,%%mm7\n");
print("\tpaddd\t%%mm7,%%mm0\n");
print("\tmovd\t%%mm0,%%eax\n");
}
static void reduceCall(Node p,char *op,int negate)
{
if (p->x.nestedCall) {
if (op == NULL)
print("\tpopl\t%%eax\n\tpopl\t%%ecx\n");
else
popNestedCall(p);
}
if (op) {
print("\tmovq\t(%%edx),%%mm4\n");
}
print("\tmovl\t$0x01010101,%%edx\n\tpushl\t%%edx\n\tpushl\t%%edx\n");
print("\tmovq\t(%%esp),%%mm1\n\txor\t%%edx,%%edx\n");
print("\tmovb\t$0xFF,%%dl\n\tpushl\t%%edx\n\tpushl\t%%edx\n");
print("\tmovq\t(%%esp),%%mm2\n\tpxor\t%%mm7,%%mm7\n\taddl\t$16,%%esp\n");
print("\torl\t%%ecx,%%ecx\n\tje\t_$LM%d\n",labelIdx+1);
if (negate) {
print("\tpcmpeqb\t%%mm5,%%mm5\n");
}
print("_$LM%d:\n",labelIdx);
print("\tdecl\t%%ecx\n");
print("\tmovq\t(%%eax,%%ecx,8),%%mm0\n");
if (op) {
print("\t");
outs(op);
print("\t%%mm4,%%mm0\n");
}
if (negate) {
print("\tpandn\t%%mm5,%%mm0\n");
}
print("\tpand\t%%mm1,%%mm0\n");
print("\tmovq\t%%mm0,%%mm3\n");
print("\tpsrlq\t$8,%%mm3\n");
print("\tpaddb\t%%mm3,%%mm0\n");
print("\tpsrlq\t$8,%%mm3\n");
print("\tpaddb\t%%mm3,%%mm0\n");
print("\tpsrlq\t$8,%%mm3\n");
print("\tpaddb\t%%mm3,%%mm0\n");
print("\tpand\t%%mm2,%%mm0\n");
print("\tpaddd\t%%mm0,%%mm7\n");
print("\tjne\t_$LM%d\n",labelIdx);
print("_$LM%d:\n\tmovd\t%%mm7,%%eax\n",labelIdx+1);
print("\tpsrlq\t$32,%%mm7\n\tmovd\t%%mm7,%%ecx\n\taddl\t%%ecx,%%eax\n");
labelIdx += 2;
}
static void mmxImmCall(Node p,char *op)
{
mmxImmCallN(p,op,0);
}
static Symbol paddArgs(Node p)
{
Symbol r=NULL;
FunctionInfo.mmxCalls = 1;
switch (ArgumentsIndex) {
case 0:
if (p->x.nestedCall == 0) {
r = intreg[ECX];
p->kids[0]->syms[2] = r;
}
break;
case 1:
if (p->x.nestedCall == 0) {
r = intreg[EDX];
p->kids[0]->syms[2] = r;
}
break;
case 2:
if (p->x.nestedCall == 0) {
r = intreg[EAX];
p->kids[0]->syms[2] = r;
}
break;
default:
assert(0);
break;
}
ArgumentsIndex++;
if (p->x.nestedCall == 0)
p->syms[2] = r;
if (ArgumentsIndex == 3)
ArgumentsIndex = 0;
return r;
}
static void itobcd(Node p)
{
if (p->x.nestedCall) {
print("\tpopl\t%%edx\n");
print("\tfildl\t(%%esp)\n\tfbstp\t(%%edx)\n\taddl\t$4,%%esp\n");
}
else {
print("\tpushl\t%%ecx\n\tfildl\t(%%esp)\n");
print("\tfbstp\t(%%edx)\n\taddl\t$4,%%esp\n");
}
}
static Symbol itobcdArgs(Node p)
{
Symbol r=NULL;
switch (ArgumentsIndex) {
case 0:
if (p->x.nestedCall == 0) {
r = intreg[ECX];
p->kids[0]->syms[2] = r;
}
break;
case 1:
if (p->x.nestedCall == 0) {
r = intreg[EDX];
p->kids[0]->syms[2] = r;
}
break;
}
ArgumentsIndex++;
if (p->x.nestedCall == 0)
p->syms[2] = r;
if (ArgumentsIndex == 2)
ArgumentsIndex = 0;
return r;
}
static Symbol reduceArgs(Node p)
{
Symbol r=NULL;
switch (ArgumentsIndex) {
case 0:
if (p->x.nestedCall == 0) {
r = intreg[ECX];
p->kids[0]->syms[2] = r;
}
break;
case 1:
if (p->x.nestedCall == 0) {
r = intreg[EAX];
p->kids[0]->syms[2] = r;
}
break;
}
ArgumentsIndex++;
if (p->x.nestedCall == 0)
p->syms[2] = r;
if (ArgumentsIndex == 2)
ArgumentsIndex = 0;
return r;
}
#if 0
static Symbol memopArgs(Node p)
{
Symbol r=NULL;
Value v;
FunctionInfo.memmove = 1;
switch (ArgumentsIndex) {
case 0:
Arg0 = NULL;
if (p->x.nestedCall == 0 ) {
r = intreg[ECX];
p->kids[0]->syms[2] = r;
if (generic(p->kids[0]->op) == CNST) {
Arg0 = p->kids[0]->syms[0];
v.u = p->kids[0]->syms[0]->u.value/4;
p->kids[0]->syms[0] = constant(inttype,v);
ArgumentsTab[0] = p->kids[0];
}
}
break;
case 1:
if (p->x.nestedCall == 0) {
r = intreg[EAX];
p->kids[0]->syms[2] = r;
}
if (generic(p->kids[0]->op) == CNST)
Arg1 = p->kids[0]->syms[0];
else {
Arg1 = NULL;
if (Arg0) {
ArgumentsTab[0]->syms[0] = Arg0;
Arg0 = NULL;
}
}
break;
case 2:
if (p->x.nestedCall == 0) {
if ((freemask[0] & (1 << EDI)) == 0)
r = intreg[EDX];
else
r = intreg[EDI];
p->kids[0]->syms[2] = r;
}
break;
default:
assert(0);
break;
}
ArgumentsIndex++;
if (p->x.nestedCall == 0)
p->syms[2] = r;
if (ArgumentsIndex == 3)
ArgumentsIndex = 0;
return r;
}
static void imemset(Node p)
{
int qty;
if (p->x.nestedCall) {
print("\tpop\t%%edx\n\tpop\t%%eax\n\tpop\t%%ecx\n");
}
if ((freemask[0] & (1 << EDI)) == 0)
print("\txchg\t%%edi,%%edx\n");
if (Arg0 && Arg1 && Arg1->u.value == 0 && Arg1->name[0] == '0') {
qty = Arg0->u.value;
qty -= 4*(qty/4);
print("\trep\n\tmovsl\n");
if (qty > 0) {
if (qty >= 2) {
print("\tmovsw\n");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -