void DoMod( void ) { stack_entry *left; union { signed_64 s; unsigned_64 u; } dummy; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: if( U64Test( &ExprSP->v.uint ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_MOD ) ); } if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) { U64Div( &left->v.uint, &ExprSP->v.uint, &dummy.u, &left->v.uint ); } else { I64Div( &left->v.sint, &ExprSP->v.sint, &dummy.s, &left->v.sint ); } break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoShift( void ) { stack_entry *left; int shift; left = StkEntry( 1 ); RValue( ExprSP ); ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 0 ); shift = I32FetchTrunc( ExprSP->v.sint ); RValue( left ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: if( shift >= 0 ) { U64ShiftL( &left->v.uint, shift, &left->v.uint ); } else if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) { U64ShiftR( &left->v.uint, -shift, &left->v.uint ); } else { I64ShiftR( &left->v.sint, -shift, &left->v.sint ); } break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoMul( void ) { stack_entry *left; xreal re, im, t1, t2; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Mul( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); break; case TK_REAL: LDMul( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: /* (a,b) * (c,d) = (ac-bd,ad+bc) */ LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDSub( &t1, &t2, &re ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t2 ); LDAdd( &t1, &t2, &im ); left->v.cmplx.re = re; left->v.cmplx.im = im; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoDiv( void ) { stack_entry *left; xreal re, im, mag, t1, t2; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: if( U64Test( &ExprSP->v.uint ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) { U64Div( &left->v.uint, &ExprSP->v.uint, &left->v.uint, NULL ); } else { I64Div( &left->v.sint, &ExprSP->v.sint, &left->v.sint, NULL ); } break; case TK_REAL: DToLD( 0.0, &t1 ); if( LDCmp( &ExprSP->v.real, &t1 ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } LDDiv( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: DToLD( 0.0, &t1 ); if( LDCmp( &ExprSP->v.cmplx.re, &t1 ) == 0 && LDCmp( &ExprSP->v.cmplx.im, &t1 ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } /* (a,b)/(c,d) = (ac+bd,bc-ad) / (c^2+d^2) */ LDMul( &ExprSP->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &ExprSP->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDAdd( &t1, &t2, &mag ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDAdd( &t1, &t2, &re ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t2 ); LDSub( &t1, &t2, &im ); LDDiv( &re, &mag, &left->v.cmplx.re ); LDDiv( &im, &mag, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoPlus( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); switch( ExprSP->info.kind ) { case TK_POINTER: case TK_ADDRESS: /* get the pointer as the left operand */ left = ExprSP; SwapStack( 1 ); } AddOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Add( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); break; case TK_POINTER: case TK_ADDRESS: switch( ExprSP->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); } if( (left->info.modifier & TM_MOD_MASK) == TM_NEAR ) { //NYI: 64 bit offsets left->v.addr.mach.offset += U32FetchTrunc( ExprSP->v.uint ); } else { //NYI: 64 bit offsets left->v.addr = AddrAdd( left->v.addr, U32FetchTrunc( ExprSP->v.uint ) ); } break; case TK_REAL: LDAdd( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: LDAdd( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re ); LDAdd( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoMinus( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); AddOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Sub( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); left->info.modifier = TM_SIGNED; break; case TK_POINTER: case TK_ADDRESS: switch( ExprSP->info.kind ) { case TK_BOOL: case TK_CHAR: case TK_ENUM: case TK_INTEGER: //NYI: 64 bit offsets left->v.addr = AddrAdd( left->v.addr, -U32FetchTrunc( ExprSP->v.uint ) ); break; case TK_POINTER: case TK_ADDRESS: I32ToI64( AddrDiff( left->v.addr, ExprSP->v.addr ), &left->v.sint ); left->info.kind = TK_INTEGER; left->info.modifier = TM_SIGNED; left->info.size = sizeof( signed_64 ); left->th = NULL; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); } break; case TK_REAL: LDSub( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: LDSub( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re ); LDSub( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
void DoXor( void ) { stack_entry *left; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Xor( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
static void DoMinusScaled( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); switch( left->info.kind ) { case TK_POINTER: switch( ExprSP->info.kind ) { case TK_POINTER: /* Have to check if base type sizes are the same */ PushBaseSize(); DupStack(); SwapStack( 3 ); PushBaseSize(); MoveSP( 1 ); SwapStack( 3 ); MoveSP( -1 ); if( !TstEQ( 1 ) ) { Error( ERR_NONE, LIT( ERR_ILL_TYPE ) ); } PopEntry(); MoveSP( 1 ); DoMinus(); MoveSP( -1 ); DoDiv(); return; default: ScaleInt(); break; } break; default: switch( ExprSP->info.kind ) { case TK_POINTER: Error( ERR_NONE, LIT( ERR_ILL_TYPE ) ); break; } } DoMinus(); }
bool PerformExplicitCall( address start, mad_string ctype, unsigned num_parms ) { bool ret; stack_entry *src; address stack; unsigned align; unsigned long amount; mad_type_info mti; stack = GetRegSP(); GetMADTypeDefaultAt( stack, MTK_INTEGER, &mti ); align = mti.b.bits / BITS_PER_BYTE; for( ; num_parms != 0; --num_parms ) { if( ExprSP->v.loc.e[0].type!=LT_ADDR && ExprSP->v.loc.e[0].u.p==NULL ) { /* push item */ src = StkEntry( 1 ); amount = (src->info.size + (align-1)) & -align; if( _IsOff( SW_STACK_GROWS_UP ) ) { stack.mach.offset -= amount; } LocationCreate( &ExprSP->v.loc, LT_ADDR, &stack ); if( _IsOn( SW_STACK_GROWS_UP ) ) { stack.mach.offset += amount; } ExprSP->info = src->info; ExprSP->flags |= SF_LOCATION; ExprSP->th = NULL; } SwapStack( 1 ); DoAssign(); PopEntry(); } AddrFix( &start ); SetRegSP( stack ); MADCallBuildFrame( ctype, start, start, &DbgRegs->mr, &DbgRegs->mr ); DbgTmpBrk.loc.addr = start; NullStatus( &DbgTmpBrk ); DbgTmpBrk.status.b.active = TRUE; ret = CallRoutine(); NullStatus( &DbgTmpBrk ); return( ret ); }
static void DoPlusScaled( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); switch( left->info.kind ) { case TK_POINTER: ScaleInt(); break; default: switch( ExprSP->info.kind ) { case TK_POINTER: SwapStack( 1 ); ScaleInt(); break; } } DoPlus(); }
static unsigned MechStack( unsigned select, unsigned parm ) { unsigned result = 0; stack_entry *entry; sym_info info; switch( select ) { case 0: SwapStack( parm ); break; case 1: MoveSP( parm ); break; case 2: entry = StkEntry( parm ); LValue( entry ); result = TypeInfoToClass( &entry->info ) & (BASE_TYPE | STK_UNSIGNED); break; case 3: ExprValue( StkEntry( parm ) ); break; case 4: LValue( StkEntry( parm ) ); break; case 5: RValue( StkEntry( parm ) ); break; case 6: LRValue( StkEntry( parm ) ); break; case 7: entry = StkEntry( parm ); LValue( entry ); result = TI_CREATE( entry->info.kind, TM_NONE, 0 ); break; case 8: entry = StkEntry( parm ); NameResolve( entry, FALSE ); if( entry->flags & SF_SYM ) { SymInfo( entry->v.sh, entry->lc, &info ); result = info.kind; } else { result = SK_NONE; } break; case 9: entry = StkEntry( parm ); result = NameResolve( entry, FALSE ); break; case 10: entry = StkEntry( parm ); if( entry->flags & SF_NAME ) { result = 0; } else if( entry->flags & SF_SYM ) { result = 1; } else if( entry->flags & SF_LOCATION ) { result = 2; } else { result = 3; } break; } return( result ); }