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

📄 codeavr.c

📁 Outputs messages to a 2line LCD
💻 C
📖 第 1 页 / 共 4 页
字号:
        	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 + -