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 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 ExpOp( TYPE typ1, TYPE typ2, OPTR opr ) { //=============================================== // Generate code to perform exponentiation. if( UnaryMul( typ1, typ2 ) ) { PushOpn( CITNode ); EmitOp( FC_UNARY_MUL ); GenType( CITNode ); OutU16( ITIntValue( CITNode->link ) ); SetOpn( CITNode, USOPN_SAFE ); } else { BinOp( typ1, typ2, opr ); } }
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 ); }