Line 54... |
Line 54... |
memset(semaphores,0,sizeof(semaphores));
|
memset(semaphores,0,sizeof(semaphores));
|
throwlab = nextlabel++;
|
throwlab = nextlabel++;
|
while( lc_auto & 7 ) /* round frame size to word */
|
while( lc_auto & 7 ) /* round frame size to word */
|
++lc_auto;
|
++lc_auto;
|
if (sym->IsInterrupt) {
|
if (sym->IsInterrupt) {
|
GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8));
|
//GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8));
|
GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE));
|
//GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE));
|
}
|
}
|
if (!sym->IsNocall) {
|
if (!sym->IsNocall) {
|
GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(24));
|
GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(24));
|
// For a leaf routine don't bother to store the link register or exception link register.
|
// For a leaf routine don't bother to store the link register or exception link register.
|
if (sym->IsLeaf)
|
if (sym->IsLeaf)
|
GenerateDiadic(op_sw,0,makereg(27),make_indirect(30));
|
GenerateDiadic(op_sw,0,makereg(27),make_indirect(30));
|
else {
|
else {
|
GenerateDiadic(op_sm, 0, make_indirect(30), make_mask(0x98000000));
|
GenerateDiadic(op_sw, 0, makereg(27), make_indexed(0,30));
|
|
GenerateDiadic(op_sw, 0, makereg(28), make_indexed(8,30));
|
|
GenerateDiadic(op_sw, 0, makereg(31), make_indexed(16,30));
|
GenerateDiadic(op_lea,0,makereg(28),make_label(throwlab));
|
GenerateDiadic(op_lea,0,makereg(28),make_label(throwlab));
|
}
|
}
|
GenerateDiadic(op_mov,0,makereg(27),makereg(30));
|
GenerateDiadic(op_mov,0,makereg(27),makereg(30));
|
if (lc_auto)
|
if (lc_auto)
|
GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(lc_auto));
|
GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(lc_auto));
|
Line 83... |
Line 85... |
GenerateDiadic(op_mov,0,makereg(31),makereg(28));
|
GenerateDiadic(op_mov,0,makereg(31),makereg(28));
|
GenerateDiadic(op_bra,0,make_label(retlab),NULL); // goto regular return cleanup code
|
GenerateDiadic(op_bra,0,make_label(retlab),NULL); // goto regular return cleanup code
|
}
|
}
|
}
|
}
|
else {
|
else {
|
GenerateDiadic(op_lw,0,makereg(31),make_indexed(16,27)); // load throw return address from stack into LR
|
GenerateDiadic(op_lw,0,makereg(31),make_indexed(8,27)); // load throw return address from stack into LR
|
GenerateDiadic(op_sw,0,makereg(31),make_indirect(27)); // and store it back (so it can be loaded with the lm)
|
GenerateDiadic(op_sw,0,makereg(31),make_indexed(16,27)); // and store it back (so it can be loaded with the lm)
|
GenerateDiadic(op_bra,0,make_label(retlab),NULL); // goto regular return cleanup code
|
GenerateDiadic(op_bra,0,make_label(retlab),NULL); // goto regular return cleanup code
|
}
|
}
|
}
|
}
|
|
|
|
|
Line 97... |
Line 99... |
void GenerateReturn(SYM *sym, Statement *stmt)
|
void GenerateReturn(SYM *sym, Statement *stmt)
|
{
|
{
|
AMODE *ap;
|
AMODE *ap;
|
int nn;
|
int nn;
|
int lab1;
|
int lab1;
|
|
int cnt;
|
|
|
if( stmt != NULL && stmt->exp != NULL )
|
if( stmt != NULL && stmt->exp != NULL )
|
{
|
{
|
initstack();
|
initstack();
|
ap = GenerateExpression(stmt->exp,F_REG|F_IMMED,8);
|
ap = GenerateExpression(stmt->exp,F_REG|F_IMMED,8);
|
Line 122... |
Line 125... |
GenerateDiadic(op_sb,0,makereg(0),make_string(semaphores[nn]));
|
GenerateDiadic(op_sb,0,makereg(0),make_string(semaphores[nn]));
|
if (sym->IsNocall) // nothing to do for nocall convention
|
if (sym->IsNocall) // nothing to do for nocall convention
|
return;
|
return;
|
// Restore registers used as register variables.
|
// Restore registers used as register variables.
|
if( save_mask != 0 ) {
|
if( save_mask != 0 ) {
|
if (bitsset(save_mask) < 2) {
|
cnt = (bitsset(save_mask)-1)*8;
|
for (nn = 31; nn >=1 ; nn--)
|
for (nn = 31; nn >=1 ; nn--) {
|
if (save_mask & (1 << nn))
|
if (save_mask & (1 << nn)) {
|
GenerateTriadic(op_lw,0,makereg(nn),make_indirect(30),NULL);
|
GenerateTriadic(op_lw,0,makereg(nn),make_indexed(cnt,30),NULL);
|
|
cnt -= 8;
|
}
|
}
|
else
|
}
|
GenerateTriadic(op_lm,0,make_indirect(30),make_mask(save_mask),NULL);
|
GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(popcnt(save_mask)*8));
|
}
|
}
|
// Unlink the stack
|
// Unlink the stack
|
// For a leaf routine the link register and exception link register doesn't need to be saved/restored.
|
// For a leaf routine the link register and exception link register doesn't need to be saved/restored.
|
GenerateDiadic(op_mov,0,makereg(30),makereg(27));
|
GenerateDiadic(op_mov,0,makereg(30),makereg(27));
|
if (sym->IsLeaf)
|
if (sym->IsLeaf)
|
GenerateDiadic(op_lw,0,makereg(27),make_indirect(30));
|
GenerateDiadic(op_lw,0,makereg(27),make_indirect(30));
|
else
|
else {
|
GenerateDiadic(op_lm,0,make_indirect(30),make_mask(0x98000000));
|
GenerateDiadic(op_lw,0,makereg(27),make_indirect(30));
|
|
GenerateDiadic(op_lw,0,makereg(28),make_indexed(8,30));
|
|
GenerateDiadic(op_lw,0,makereg(31),make_indexed(16,30));
|
|
}
|
//if (isOscall) {
|
//if (isOscall) {
|
// GenerateDiadic(op_move,0,makereg(0),make_string("_TCBregsave"));
|
// GenerateDiadic(op_move,0,makereg(0),make_string("_TCBregsave"));
|
// gen_regrestore();
|
// gen_regrestore();
|
//}
|
//}
|
// Generate the return instruction. For the Pascal calling convention pop the parameters
|
// Generate the return instruction. For the Pascal calling convention pop the parameters
|
// from the stack.
|
// from the stack.
|
if (sym->IsInterrupt) {
|
if (sym->IsInterrupt) {
|
GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(24));
|
//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(24));
|
GenerateDiadic(op_lm,0,make_indirect(30),make_mask(0x9FFFFFFE));
|
//GenerateDiadic(op_lm,0,make_indirect(30),make_mask(0x9FFFFFFE));
|
GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(popcnt(0x9FFFFFFE)*8));
|
//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(popcnt(0x9FFFFFFE)*8));
|
GenerateDiadic(op_iret,0,NULL,NULL);
|
GenerateMonadic(op_iret,0,NULL);
|
return;
|
return;
|
}
|
}
|
if (sym->IsPascal)
|
if (sym->IsPascal)
|
GenerateDiadic(op_ret,0,make_immed(24+sym->NumParms * 8),NULL);
|
GenerateDiadic(op_ret,0,make_immed(24+sym->NumParms * 8),NULL);
|
else
|
else
|
Line 230... |
Line 237... |
if( result->preg != 1 || (flags & F_REG) == 0 )
|
if( result->preg != 1 || (flags & F_REG) == 0 )
|
if (sym) {
|
if (sym) {
|
if (sym->tp->btp->type==bt_void)
|
if (sym->tp->btp->type==bt_void)
|
;
|
;
|
else
|
else
|
GenerateTriadic(op_or,0,result,makereg(1),makereg(0));
|
GenerateDiadic(op_mov,0,result,makereg(1));
|
}
|
}
|
else
|
else
|
GenerateTriadic(op_or,0,result,makereg(1),makereg(0));
|
GenerateDiadic(op_mov,0,result,makereg(1));
|
return result;
|
return result;
|
}
|
}
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|