📄 codeavr.c
字号:
outstr("+2,r27\n");
ot("sts\t");
outstr(stack[stkptr].name);
outstr("+3,r26\n");
stkptr--;
}
// else
// if (stpt->storage == PUBLIC) {
// ol("st\tx+,r31");
// ol("st\tx+,r30");
// ol("st\tx+,r27");
// ol("st\tx+,r26");
// }
else {
gcall("putstk_l", CINT);
stkp += 2;
}
}
else {
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);
stkp += INTSIZE;
}
else {
// if (stpt->storage == PUBLIC) {
// ol("st\tx+,r31");
// ol("st\tx+,r30");
// }
// else {
gcall("putstk_i_z", CINT);
stkp += INTSIZE;
// }
}
}
}
}
// Fetch the specified object type indirect through the primary
// register into the primary register. stpt-type is the type we
// are loading from, stpt->cast is the type we are loading to,
// or zero.
void indirect(STATE *stpt) {
int type;
if (!stpt->pointing && stpt->ident == POINTER) {
if (InX) {
ol("ld\tr31,x+");
ol("ld\tr30,x+");
}
else {
ol("ld\tr0,z+");
ol("ld\tr30,z+");
ol("mov\tr31,r0");
}
InX = 0;
return;
}
if (stpt->cast)
type = stpt->cast;
else
type = stpt->type;
if (type == CCHAR || type == UCCHAR) {
if (!(stpt->type == UCCHAR || stpt->type == CCHAR)) {
if (InX) {
if (stpt->type == CINT || stpt->type == UCINT)
ol("adiw\tr26,1");
else
if (stpt->type == CLONG)
ol("adiw\tr26,3");
ol("ld\tr30,x");
}
else {
ot("ldd\tr30,z");
if (stpt->type == CINT || stpt->type == UCINT)
outstr("+1\n");
else
if (stpt->type == CLONG)
outstr("+3\n");
else
outstr("+0\n");
}
InX = 0;
}
else {
if (InX) {
// if (stpt->funcpar || (CallFunction && stpt->ident != POINTER))
// ol("adiw\tr26,1");
ol("ld\tr30,x");
InX = 0;
}
else {
ol("ld\tr30,z");
// ot("ldd\tr30,z");
// if (stpt->funcpar || (CallFunction && stpt->ident != POINTER))
// outstr("+1");
// else
// outstr("+0");
// nl();
}
}
if (type == CCHAR)
sign_extend_int(stpt);
else
ol("clr\tr31");
}
else
if (type == CINT || type == UCINT || type == VOID) {
if (stpt->type == CLONG || stpt->type == CCHAR || stpt->type == UCCHAR) {
if (stpt->type == CLONG) {
ol("ldd\tr0,z+3");
ol("ldd\tr31,z+2");
ol("mov\tr30,r0");
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
if (InX) {
ol("ld\tr30,x");
InX = 0;
}
else {
ol("ld\tr26,z");
InX = 1;
}
}
}
else {
// ol("ldd\tr0,z+1");
// ol("ld\tr31,z");
// ol("mov\tr30,r0");
if (InX) {
ol("ld\tr31,x+");
ol("ld\tr30,x+");
InX = 0;
}
else {
ol("ld\tr27,z+");
ol("ld\tr26,z+");
InX = 1;
}
}
}
else {
if (stpt->type != CLONG) {
if (stpt->type == CINT || stpt->type == UCINT) {
if (InX) {
ol("mov\tr31,r27");
ol("mov\tr30,r26");
}
ol("ldd\tr0,z+1");
ol("ld\tr31,z");
ol("mov\tr30,r0");
InX = 0;
}
else
if (stpt->type == CCHAR || stpt->type == UCCHAR) {
ol("ld\tr30,z");
}
}
else {
gcall("glpp", CINT);
}
}
}
// Fetch the specified CONSTANT object type indirect through the
// primary register into the primary register
void ld_constant(STATE *stpt) {
int type;
if (stpt->cast)
type = stpt->cast;
else
type = stpt->type;
if (type == CCHAR || type == UCCHAR) {
if (InX) {
ol("mov\tr31,r27");
ol("mov\tr30,r26");
}
ol("lpm");
ol("mov\tr30,r0");
ol("clr\tr31");
InX = 0;
}
else
if (type == CINT || type == UCINT)
gcall("loadc_i", CINT);
else
if (type == CLONG)
gcall("loadc_l", CINT);
}
// swap the primary and secondary registers
void swap(void) {
ol("st\t-y,r26"); // push secondary
ol("st\t-y,r27");
gpush(CINT); // push primary
gpop(CINT); // pop secondary
ol("ld\tr31,y+"); // pop primary
ol("ld\tr30,y+");
}
// Push the primary register onto the stack.
// MSB always goes to the lowest address.
int gpush(int type) {
// if (stkptr == 1 && stack[stkptr].storage == PUBLIC)
// return;
CINTpushPending = 0;
if (type == CLONG) {
gcall("push_l", CINT);
stkp -= 4;
return 4;
}
// else
// if (type == UCCHAR) {
// if (InX)
// ol("st\t-y,r26");
// else
// ol("st\t-y,r30");
// stkp -= 1;
// return (1);
// }
else {
if (InX) {
ol("st\t-y,r26");
ol("st\t-y,r27");
}
else {
ol("st\t-y,r30");
ol("st\t-y,r31");
}
stkp -= INTSIZE;
return INTSIZE;
}
}
// pop the top of the stack into the secondary register
void gpop(int type) {
if (type == CLONG) {
gcall("pop_l", CINT);
stkp += 4;
}
else {
// if (type == CINT || type == CCHAR || type == VOID) {
if (InX) {
ol("ld\tr31,y+");
ol("ld\tr30,y+");
InX = 0;
}
else {
ol("ld\tr27,y+");
ol("ld\tr26,y+");
InX = 1;
}
// if (!(type == ARRAY || type == POINTER))
stkp += INTSIZE;
// }
// else {
// ol("ld\tr26,y+");
// stkp += 1;
}
}
// swap the primary register and the top of the stack
void swapstk(void) {
gpop(CINT);
gpush(CINT);
x2z();
}
// call the specified subroutine name
void gcall(char *sname, int type) {
char lname[200];
strcpy(lname, sname);
if (type == CLONG)
strcat(lname,"_l");
if (!CheckExtFun(sname)) {
ot("extern\t");
internal_prefix();
outstr(lname);
nl();
}
ot("rcall\t");
internal_prefix();
outstr(lname);
nl();
}
// Call the specified user subroutine name
void ucall(char *sname) {
ot("rcall\t");
LabPrefix();
outstr(sname);
nl();
}
// return from subroutine
void gret(void) {
ol("ret");
}
// perform subroutine call to value on top of stack
void callstk(void) {
if (InX) {
ol("mov\tr31,r27");
ol("mov\tr30,r26");
}
ol("icall");
// stkp = stkp + INTSIZE; // need to check this for ALL push/pops
}
// jump to specified internal label number
void jump(int label) {
ot("rjmp\t");
printlabel(label);
nl();
LabelCount[label]++;
}
// test the primary register and jump as required to label
void testjump(int label, int ft, int type) {
// if (type == CCHAR) {
// if (InX)
// ol("or\tr26,r26");
// else
// ol("or\tr30,r30");
// }
// else {
if (InX)
ol("or\tr27,r26");
else
ol("or\tr31,r30");
// }
if (type == CLONG) {
ol("or\tr31,r27");
ol("or\tr31,r26");
}
if (ft)
ol("breq\t$+4");
else
ol("brne\t$+4");
}
void testgt0(int label, int ft, int type) {
// Check if it is negative
if (type == CLONG) {
ol("tst\tr31");
ol("brmi\t$+10");
}
else
if (type == CINT) {
if (InX)
ol("tst\tr27");
else
ol("tst\tr31");
ol("brmi\t$+6");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
ol("brmi\t$+6");
}
// Check if it is zero
if (type == CLONG) {
ol("or\tr27,r26");
ol("or\tr31,r30");
ol("or\tr31,r27");
}
else
if (type == CINT) {
if (InX)
ol("or\tr27,r26");
else
ol("or\tr31,r30");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
}
ol("brne\t$+4");
}
void testlt0(int label, int ft, int type) {
// If it is negative...
if (type == CLONG)
ol("tst\tr31");
else
if (type == CINT) {
if (InX)
ol("tst\tr27");
else
ol("tst\tr31");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
}
ol("brmi\t$+4");
}
void testgteq0(int label, int ft, int type) {
// As long as it is not negative
if (type == CLONG)
ol("tst\tr31");
else
if (type == CINT) {
if (InX)
ol("tst\tr27");
else
ol("tst\tr31");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
}
ol("brpl\t$+4");
}
void testlteq0(int label, int ft, int type) {
// Check if it is negative
if (type == CLONG) {
ol("tst\tr31");
ol("brmi\t$+12");
}
else
if (type == CINT) {
if (InX)
ol("tst\tr27");
else
ol("tst\tr31");
ol("brmi\t$+8");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
ol("brmi\t$+8");
}
// Check if it is zero
if (type == CLONG) {
ol("or\tr27,r26");
ol("or\tr31,r30");
ol("or\tr31,r27");
}
else
if (type == CINT) {
if (InX)
ol("or\tr27,r26");
else
ol("or\tr31,r30");
}
else
if (type == CCHAR) {
if (InX)
ol("tst\tr26");
else
ol("tst\tr30");
}
ol("breq\t$+4");
}
// print pseudo-op to define a byte
void defbyte(void) {
ot("db\t");
}
// print pseudo-op to define storage
void defstorage(void) {
ot("ds\t");
}
// print pseudo-op to define a word
void defword(void) {
ot("dw\t");
}
// Modify the stack pointer to the new value indicated
int modstk(int newstkp) {
int k, n;
k = n = galign(newstkp - stkp);
if (k < 0)
n = -n;
if (PendingJump)
PendingJump = 0; // can be ignored
if (k == 0)
return (newstkp);
if (k < 0) {
if (n > 63) {
ot("subi\tr28,low(");
onum(n);
outstr(")");
nl();
ot("sbci\tr29,high(");
onum(n);
outstr(")");
}
else {
ot("sbiw\tr28,");
onum(abs(k));
}
}
else {
if (n > 63) {
ot("subi\tr28,low(");
onum(-k);
outstr(")");
nl();
ot("sbci\tr29,high(");
onum(-k);
outstr(")");
}
else {
ot("adiw\tr28,");
onum(k);
}
}
nl();
return(newstkp);
}
// multiply the primary register by INTSIZE
void gaslint(void) {
if (InX) {
ol("lsl\tr26");
ol("rol\tr27");
}
else {
ol("lsl\tr30");
ol("rol\tr31");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -