📄 codeavr.c
字号:
}
// divide the primary register by INTSIZE
void gasrint(void) {
ol("lsr\tr31");
ol("ror\tr30");
}
// Case jump instruction
void gjcase(void) {
// addglb("_case", 0, 0, 0, 0, 0);
// ptr = findglb("_case");
// symtab[ptr].used = 1;
if (!CheckExtFun("_case"))
ol("extern\t_case");
ot("rjmp\t_case");
nl();
}
// Add the primary and secondary registers
void gadd(int type) {
// if (stkptr == 0) {
// if (type < 0)
// gpop(CINT);
// else
gpop(type);
// }
if (type == CLONG) {
gcall("add_l", CINT);
}
else {
ol("add\tr26,r30");
// if (type < 0 || type == CINT)
ol("adc\tr27,r31");
InX = 1;
}
}
// Subtract the primary register from the secondary.
// Move answer to primary.
void gsub(int type) {
gpop(type);
if (type == CLONG)
gcall("sub_l", CINT);
else {
if (InX) {
ol("sub\tr26,r30");
ol("sbc\tr27,r31");
}
else {
ol("sub\tr30,r26");
ol("sbc\tr31,r27");
}
}
}
// Multiply the primary and secondary registers.
// For INTs, result in primary, overflow in secondary.
void gmult(int type) {
gpop(type);
gcall("mul", type);
}
void umult(int type) {
gpop(type);
gcall("umul", type);
}
// divide the secondary register by the primary
// (quotient in primary, remainder in secondary)
void gdiv(int type) {
gpop(type);
gcall("div", type);
}
void udiv(int type) {
gpop(type);
gcall("udiv", type);
}
// compute the remainder (mod) of the secondary register
// divided by the primary register
// (remainder in primary, quotient in secondary)
void gmod(int type) {
gdiv(type);
if (type == CINT)
x2z();
else
x2zL();
}
void umod(int type) {
udiv(type);
if (type == CINT)
x2z();
else
x2zL();
}
void x2zL(void) {
ol("mov\tr31,r25");
ol("mov\tr30,r24");
ol("mov\tr27,r23");
ol("mov\tr26,r22");
}
// inclusive 'or' the primary and secondary registers
void gor(int type) {
gpop(type);
if (type == CLONG)
gcall("or", type);
else {
ol("or\tr30,r26");
ol("or\tr31,r27");
InX = 0;
}
}
// exclusive 'or' the primary and secondary registers
void gxor(int type) {
gpop(type);
if (type == CLONG)
gcall("xor", type);
else {
ol("eor\tr30,r26");
ol("eor\tr31,r27");
InX = 0;
}
}
// 'and' the primary and secondary registers
void gand(int type) {
gpop(type);
if (type == CLONG)
gcall("and", type);
else {
ol("and\tr30,r26");
ol("and\tr31,r27");
InX = 0;
}
}
// arithmetic shift right the secondary register the number of
// times in the primary register
// (results in primary register)
void gasr(int type) {
if (type == CLONG) {
ol("mov\tr25,r31");
ol("mov\tr24,r30");
ol("rcall\t_pop_l_p");
ol("rcall\t_lsr_l");
}
else {
gpop(type);
gcall("lsr", type);
x2z();
InX = 0;
}
}
// arithmetic shift left the secondary register the number of
// times in the primary register
// (results in primary register)
void gasl(int type) {
if (type == CLONG) {
ol("mov\tr25,r31");
ol("mov\tr24,r30");
ol("rcall\t_pop_l_p");
ol("rcall\t_lsl_l");
}
else {
gpop(type);
gcall("lsl", type);
x2z();
InX = 0;
}
}
// two's complement of primary register
void gneg(int type) {
if (type == CLONG)
gcall("neg", type);
else {
ol("com\tr30");
ol("com\tr31");
ol("adiw\tr30,1");
InX = 0;
}
}
// logical complement of primary register
void glneg(int type) {
if (InX) {
ol("mov\tr31,r27");
ol("mov\tr30,r26");
}
gcall("bool", type);
InX = 0;
}
// one's complement of primary register
void gcom(int type) {
if (type == CLONG)
gcall("com", type);
else {
if (InX) {
ol("com\tr26");
ol("com\tr27");
}
else {
ol("com\tr30");
ol("com\tr31");
}
}
}
// Convert primary value into logical value (0 if 0, 1 otherwise)
void gbool(int type) {
gcall("bool", type);
}
// Increment the primary register by 1 if not a POINTER, otherwise
// by the pointer size.
void ginc(STATE *stpt) {
// IncPending = 0;
if (symtab[stpt->ptr].ident == POINTER) {
if (stpt->type == CLONG) {
if (InX)
ol("adiw\tr26,4");
else
ol("adiw\tr30,4");
}
else
if (stpt->type == CINT || stpt->type == UCINT) {
if (InX)
ol("adiw\tr26,2");
else
ol("adiw\tr30,2");
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
if (InX)
ol("adiw\tr26,1");
else
ol("adiw\tr30,1");
}
else
if (stpt->type == CSTRUCT) {
if (InX)
ot("adiw\tr30,");
else
ot("adiw\tr30,");
onum(symtab[symtab[stpt->ptr].pntrpntr].PerEntry);
nl();
}
else
if (stpt->type == STRUCTINST) {
if (InX)
ot("adiw\tr26,");
else
ot("adiw\tr30,");
onum(symtab[symtab[stpt->ptr].pntrpntr].offset);
nl();
}
}
else {
if (symtab[stpt->ptr].type == CLONG) {
ol("adiw\tr26,1");
ol("brcc\t$+4");
ol("adiw\tr30,1");
}
else {
if (InX)
ol("adiw\tr26,1");
else
ol("adiw\tr30,1");
}
}
}
// decrement the primary register by one if char, INTSIZE if int
void gdec(STATE *stpt) {
// DecPending = 0;
if (symtab[stpt->ptr].ident == POINTER) {
if (stpt->type == CLONG) {
if (InX)
ol("sbiw\tr30,4");
else
ol("sbiw\tr30,4");
}
else
if (stpt->type == CINT) {
if (InX)
ol("sbiw\tr26,2");
else
ol("sbiw\tr30,2");
}
else {
if (InX)
ol("sbiw\tr26,1");
else
ol("sbiw\tr30,1");
}
}
else {
if (symtab[stpt->ptr].type == CLONG) {
ol("sbiw\tr26,1");
ol("sbci\tr30,0");
ol("sbci\tr31,0");
}
else {
if (InX)
ol("sbiw\tr26,1");
else
ol("sbiw\tr30,1");
}
}
}
// Following are the conditional operators.
// They compare the secondary register against the primary register
// and will branch if the condition tested for is TRUE.
// equal
void geq(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr30,r26");
ol("sbc\tr31,r27");
}
ol("breq\t$+4");
InX = 0;
}
// not equal
void gne(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr30,r26");
ol("sbc\tr31,r27");
}
ol("brne\t$+4");
InX = 0;
}
// less than (signed)
void glt(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr26,r30");
ol("sbc\tr27,r31");
}
ol("brlo\t$+4");
InX = 1;
}
// less than or equal (signed)
void gle(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr30,r26");
ol("sbc\tr31,r27");
}
ol("brge\t$+4");
InX = 0;
}
// greater than (signed)
void ggt(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr30,r26");
ol("sbc\tr31,r27");
}
ol("brlo\t$+4");
}
// greater than or equal (signed)
void gge(int type) {
gpop(type);
if (type == CLONG)
ol("rcall\t_cmp_l");
else {
ol("sub\tr26,r30");
ol("sbc\tr27,r31");
}
ol("brge\t$+4");
}
//********************************************************
// less than (unsigned)
void gult(int type) {
gpop(type);
// gcall("ult", type);
ol("sub\tr26,r30");
if (type == UCINT)
ol("sbc\tr27,r31");
ol("brlo\t$+4");
}
// less than or equal (unsigned)
void gule(int type) {
gpop(type);
// gcall("ule", type);
ol("sub\tr30,r26");
if (type == UCINT)
ol("sbc\tr31,r27");
ol("brge\t$+4");
}
// greater than (unsigned)
void gugt(int type) {
gpop(type);
// gcall("ugt", type);
ol("sub\tr26,r30");
if (type == UCINT)
ol("sbc\tr27,r31");
ol("brlo\t$+4");
}
// greater than or equal (unsigned)
void guge(int type) {
gpop(type);
// gcall("uge", type);
ol("sub\tr26,r30");
if (type == UCINT)
ol("sbc\tr27,r31");
ol("brsh\t$+4");
}
//*******************************************************
static char *incp;
char *GetIncs(char *name) {
static char *p;
char *q;
if (incp == NULL)
{
incp = (char *)getenv(name);
if (incp)
{
if (*incp == ';')
incp++;
p = q = incp;
}
else
return NULL;
}
else
{
if (*p == ';')
p++;
q = p;
}
while (*p && *p != ';')
p++;
strncpy(line, q, p-q);
line[p-q] = '\0';
if (p-q)
return line;
else
return NULL;
}
// Squirrel away argument count in a register that modstk
// doesn't touch.
void gnargs(int d)
{
}
// Run the assembler immediately after compiling
static char linkline[150];
static char buf[300];
int assemble(char *s) {
char *p;
if (strlen(linkline)) {
strcat(linkline, " ");
strcat(linkline, module);
}
else
strcpy(linkline, module);
sprintf(buf, "aa90 -r -L -v%d ", Vtype);
incp = NULL;
while (p = GetIncs("INCLUDE")) {
strcat(buf, "-I");
strcat(buf, p);
strcat(buf, " ");
}
strcat(buf, module);
strcat(buf, " -o ");
strcat(buf, module);
printf("%s\n", buf);
return (system(buf));
}
// Run the linker
int link(void) {
char *p;
strcpy(buf, "xlink crti libcavr ");
strcat(buf, linkline);
incp = NULL;
while (p = GetIncs("LIB")) {
strcat(buf, " -I");
strcat(buf, p);
}
strcat(buf, " -ca90 -Z(DATA)sdata=60 -Z(CODE)scode=0 -Fintel-standard -o ");
strcat(buf, linkline);
strcat(buf, ".hex -xsem -l map");
printf("%s\n", buf);
system(buf);
strcpy(buf, "xlink crti libcavr ");
strcat(buf, linkline);
incp = NULL;
while (p = GetIncs("LIB")) {
strcat(buf, " -I");
strcat(buf, p);
}
strcat(buf, " -ca90 -r -Z(DATA)sdata=60 -Z(CODE)scode=0 -o debug");
printf("%s\n", buf);
return (system(buf));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -