📄 codeavr.c
字号:
else
if (stkptr && stpt->type == CLONG) {
if (stkptr && stpt->storage == PUBLIC) {
ot("lds\tr31,");
outstr(stack[stkptr].name);
outstr("+0\n");
ot("lds\tr30,");
outstr(stack[stkptr].name);
outstr("+1\n");
ot("lds\tr27,");
outstr(stack[stkptr].name);
outstr("+2\n");
ot("lds\tr26,");
outstr(stack[stkptr].name);
outstr("+3\n");
stkptr--;
}
else {
if (stkptr) {
ot("ldi\tr31,high(");
outstr(stack[stkptr].name);
outstr(")\n");
ot("ldi\tr30,low(");
outstr(stack[stkptr].name);
outstr(")\n");
stkptr--;
}
else {
ol("ldd\tr26,z+3");
ol("ldd\tr27,z+2");
ol("ldd\tr0,z+1");
ol("ldd\tr31,z+0");
ol("mov\tr30,r0");
}
}
return;
}
if (stpt->cast && stpt->ident == POINTER)
error("Cannot cast a pointer");
else {
if (stpt->cast == CLONG) {
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ot("lds\tr26,");
NamePrefix();
outstr(symtab[ptr].name);
nl();
if (stpt->type == UCCHAR)
gcall("ucharlong_ext", CINT);
else
gcall("charlong_ext", CINT);
}
else
if (stpt->type == CINT) {
ot("lds\tr27,");
NamePrefix();
outstr(symtab[ptr].name);
nl();
ot("lds\tr26,");
NamePrefix();
outstr(symtab[ptr].name);
outstr("+1");
nl();
sign_extend_long(stpt);
}
else
GetMemLong(ptr, stpt->offset);
}
else
if (stpt->cast == CINT) {
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
// GetMemChar(ptr, stpt->offset);
sign_extend_int(stpt);
stpt->type = CINT;
}
else
if (stpt->type == CLONG) {
ot("lds\tr31,");
NamePrefix();
outstr(symtab[ptr].name);
outstr("+2");
nl();
ot("lds\tr30,");
NamePrefix();
outstr(symtab[ptr].name);
outstr("+3");
nl();
}
else
GetMemInt(ptr, stpt->offset);
}
else
if (stpt->cast == CCHAR) {
if (stpt->type == CLONG) {
ot("lds\tr30,");
NamePrefix();
outstr(symtab[ptr].name);
outstr("+3");
nl();
}
else
if (stpt->type == CINT) {
ot("lds\tr30,");
NamePrefix();
outstr(symtab[ptr].name);
outstr("+1");
nl();
}
else
GetMemChar(ptr, stpt->offset);
}
}
}
void sign_extend_int(STATE *stpt) {
if (stpt->type == UCCHAR) {
if (InX)
ol("clr\tr27");
else
ol("clr\tr31");
}
else {
if (InX)
gcall("sextx", CINT);
else
gcall("sextz", CINT);
}
}
void sign_extend_long(STATE *stpt) {
if (stpt->type == UCINT)
gcall("uintlong_ext", CINT);
else
gcall("intlong_ext", CINT);
}
void char2long_sign_extend(STATE *stpt) {
ol("mov\tr26,r30");
if (stpt->type == UCCHAR)
gcall("ucharlong_ext", CINT);
else
gcall("charlong_ext", CINT);
}
static GetMemChar(int ptr, int offset) {
ot("lds\tr26,");
NamePrefix();
outstr(symtab[ptr].name);
if (offset) {
outstr("+");
onum(offset);
}
nl();
ol("clr\tr27");
InX = 1;
}
static GetMemInt(int ptr, int offset) {
ot("lds\tr27,");
NamePrefix();
outstr(symtab[ptr].name);
if (offset) {
outstr("+");
onum(offset);
}
nl();
ot("lds\tr26,");
NamePrefix();
outstr(symtab[ptr].name);
if (offset) {
outstr("+");
onum(offset);
}
outstr("+1");
nl();
InX = 1;
}
static GetMemLong(int ptr, int offset) {
ot("llds\t");
NamePrefix();
outstr(symtab[ptr].name);
if (offset) {
ot("+");
onum(offset);
}
nl();
}
// fetch the address of the specified symbol into the primary register
void getloc(STATE *stpt) {
int k, ptr;
ptr = stpt->ptr;
if (symtab[ptr].storage == LSTATIC) {
immed(stpt);
printlabel(glint(ptr));
nl();
}
else {
if (stpt->type == CLONG) {
ol("mov\tr30,r28");
ol("mov\tr31,r29");
k = glint(ptr) - stkp;
if (k < 0)
error("Internal error - negative variable offset");
if (k) {
ot("adiw\tr30,");
outdec(k);
nl();
}
InX = 0;
}
else {
if (PointerFlag) {
ol("mov\tr30,r28");
ol("mov\tr31,r29");
InX = 0;
}
else {
ol("mov\tr26,r28");
ol("mov\tr27,r29");
InX = 1;
}
k = glint(ptr) - stkp;
if (k < 0)
error("Internal error - negative variable offset");
if (stpt->funcpar)
k++;
if (k) {
if (PointerFlag)
ot("adiw\tr30,");
else
ot("adiw\tr26,");
outdec(k);
nl();
}
if (PointerFlag)
InX = 0;
else
InX = 1;
}
}
}
// Store the correct register into the specified static memory cell.
// If the SubFlag is TRUE, then store the secondary register, else
// store the primary.
void putmem(STATE *stpt) {
char ttt[100], *pt;
strcpy(ttt, symtab[stpt->ptr].name);
pt = ttt + strlen(ttt) - 1;
while ((*pt == '\t') || (*pt == ' '))
*pt-- = '\0';
if (symtab[stpt->ptr].ident != POINTER && (symtab[stpt->ptr].type == CCHAR || symtab[stpt->ptr].type == UCCHAR)) {
ot("sts\t");
NamePrefix();
outstr(ttt);
if (InX)
outstr(",r26");
else
outstr(",r30");
}
else
if (symtab[stpt->ptr].ident != POINTER && symtab[stpt->ptr].type == CLONG) {
ot("sts\t");
NamePrefix();
outstr(ttt);
outstr(",r31");
nl();
ot("sts\t");
NamePrefix();
outstr(ttt);
outstr("+1,r30");
nl();
ot("sts\t");
NamePrefix();
outstr(ttt);
outstr("+2,r27");
nl();
ot("sts\t");
NamePrefix();
outstr(ttt);
outstr("+3,r26");
}
else
if (stpt->ident == ARRAY) {
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ot("st\tx,r30");
}
else {
ol("st\t-x,r30");
ot("st\t-x,r31");
}
}
else {
ot("sts\t");
NamePrefix();
outstr(ttt);
if (InX)
outstr(",r27\n");
else
outstr(",r31\n");
ot("sts\t");
NamePrefix();
outstr(ttt);
if (InX)
outstr("+1,r26");
else
outstr("+1,r30");
}
nl();
}
// Store a register variable
void putreg(STATE *stpt) {
int reg;
reg = symtab[stpt->ptr].reg & ~CONSTANT;
if (stpt->ident == POINTER || stpt->type == CINT || stpt->type == UCINT) {
ot("mov\tr");
onum(reg);
if (InX)
outstr(",r27\n");
else
outstr(",r31\n");
ot("mov\tr");
onum(reg - 1);
if (InX)
outstr(",r26\n");
else
outstr(",r30\n");
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ot("mov\tr");
onum(reg);
outstr(",r30\n");
}
else
if (stpt->type == CLONG) {
ot("mov\tr");
onum(reg);
outstr(",r31");
nl();
ot("mov\tr");
onum(reg - 1);
outstr(",r30");
nl();
ot("mov\tr");
onum(reg - 2);
outstr(",r27");
nl();
ot("mov\tr");
onum(reg - 3);
outstr(",r26");
nl();
}
}
// load a register variable into primary
void getreg(STATE *stpt) {
int reg;
reg = symtab[stpt->ptr].reg & ~CONSTANT;
if (stpt->cast == 0) {
if (stpt->ident == POINTER || stpt->type == CINT || stpt->type == UCINT) {
ot("mov\tr31,r");
onum(reg);
nl();
ot("mov\tr30,r");
onum(reg - 1);
nl();
InX = 0;
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ot("mov\tr30,r");
onum(reg);
nl();
if (IfFlag || Indexing || CallFunction)
sign_extend_int(stpt);
}
else
if (stpt->type == CLONG) {
ot("mov\tr31,r");
onum(reg);
nl();
ot("mov\tr30,r");
onum(reg - 1);
nl();
ot("mov\tr27,r");
onum(reg - 2);
nl();
ot("mov\tr26,r");
onum(reg - 3);
nl();
}
}
else
if (stpt->ident == POINTER)
error("Cannot cast a pointer");
else {
if (stpt->cast == CLONG) {
if (stpt->type == CCHAR) {
ot("mov\tr26,r");
onum(reg);
nl();
gcall("charlong_ext", CINT);
}
else
if (stpt->type == CINT) {
ot("mov\tr26,r");
onum(reg - 1);
nl();
ot("mov\tr27,r");
onum(reg);
nl();
sign_extend_long(stpt);
}
else
if (stpt->type == CLONG) {
ot("mov\tr31,r");
onum(reg);
nl();
ot("mov\tr30,r");
onum(reg - 1);
nl();
ot("mov\tr27,r");
onum(reg - 2);
nl();
ot("mov\tr26,r");
onum(reg - 3);
nl();
}
stpt->type = CLONG;
}
else
if (stpt->cast == CINT) {
if (stpt->type == CCHAR) {
ot("mov\tr30,r");
onum(reg);
nl();
sign_extend_int(stpt);
}
else
if (stpt->type == CLONG) {
ot("mov\tr30,r");
onum(reg - 3);
nl();
ot("mov\tr31,r");
onum(reg - 2);
nl();
}
else
if (stpt->type == CINT) {
ot("mov\tr31,r");
onum(reg);
nl();
ot("mov\tr30,r");
onum(reg - 1);
nl();
}
stpt->type = CINT;
}
else
if (stpt->cast == CCHAR) {
if (stpt->type == CINT || stpt->type == UCINT) {
ot("mov\tr30,r");
onum(reg - 1);
nl();
}
else
if (stpt->type == CLONG) {
ot("mov\tr30,r");
onum(reg - 3);
nl();
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ot("mov\tr30,r");
onum(reg);
nl();
}
stpt->type = CCHAR;
}
stpt->cast = 0;
}
InX = 0;
}
// Long variable sign extend
void long_sign_extend(STATE *stpt) {
if (!InX) {
ol("mov\tr26,r30");
ol("mov\tr27,r31");
}
sign_extend_long(stpt);
}
// Int variable sign extend
void int_sign_extend(STATE *stpt) {
sign_extend_int(stpt);
}
// Convert a long to int
void long2int(STATE *st2pt) {
x2z();
}
void x2z(void) {
ol("mov\tr30,r26");
ol("mov\tr31,r27");
}
// store the specified object type in the primary register
// at the address on the top of the stack
void putstk(STATE *stpt, int flag) {
if (stpt->ident == POINTER && !flag) {
if (stkptr) {
ot("sts\t");
outstr(stack[stkptr].name);
if (InX)
outstr(",r27\n");
else
outstr(",r31\n");
ot("sts\t");
outstr(stack[stkptr].name);
if (InX)
outstr("+1,r26\n");
else
outstr("+1,r30\n");
stkptr--;
}
else {
if (InX)
gcall("putstk_i_x", CINT);
else
gcall("putstk_i_z", CINT);
stkp += INTSIZE;
}
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
if (stkptr) {
ot("sts\t");
outstr(stack[stkptr].name);
if (InX)
outstr(",r26\n");
else
outstr(",r30\n");
stkptr--;
}
else {
if (InX) {
ol("mov\tr30,r26");
if (symtab[osymptr].type == CINT)
ol("mov\tr31,r27");
InX = 0;
}
gpop(CINT);
// if (stpt->funcpar)
// ol("adiw\tr26,1")
// if (InX)
// ol("st\tz,r26");
// else
ol("st\tx,r30"); // pchar code
InX = 0; // actual value is now in Z
}
}
else
if (stpt->type == CLONG) {
if (stkptr) {
ot("sts\t");
outstr(stack[stkptr].name);
outstr("+0,r31\n");
ot("sts\t");
outstr(stack[stkptr].name);
outstr("+1,r30\n");
ot("sts\t");
outstr(stack[stkptr].name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -