⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intrin.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -