#ifndef _INL68_SHIFTING_H_
#define _INL68_SHIFTING_H_
static inline
void inl_swap68(emu68_t * const emu68, int dn)
{
uint68_t v = (u32) REG68.d[dn];
REG68.d[dn] = v = ( v >> 16 ) + ( (int68_t)(u16)v << 16 );
REG68.sr = ( REG68.sr & ( 0xFF00 | SR_X ) )
| ( !v << SR_Z_BIT )
| ( ( v >> (31 - SR_N_BIT) ) & SR_N )
;
}
static inline
int68_t inl_lsl68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr;
s &= 63;
inl_addcycle68(emu68, 2*s);
if (--s < 0) {
ccr = REG68.sr & SR_X;
} else if (s > SIGN_BIT) {
d = 0;
ccr = 0;
} else {
d <<= s;
ccr = ( d >> SIGN_BIT ) & ( SR_X | SR_C );
d <<= 1;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = (REG68.sr & 0xFF00) | ccr;
return d;
}
static inline
int68_t inl_lsr68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr;
s &= 63;
inl_addcycle68(emu68, 2*s);
if (--s < 0) {
ccr = REG68.sr & SR_X;
} else if (s > SIGN_BIT) {
d = 0;
ccr = 0;
} else {
const uint68_t m = NRM_MSK(l);
d >>= s;
ccr = -( ( d >> ( SIGN_BIT - l ) ) & 1 ) & ( SR_X | SR_C );
d = ( d >> 1 ) & m;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = (REG68.sr & 0xFF00) | ccr;
return d;
}
static inline
int68_t inl_asl68(emu68_t * const emu68, int68_t d, int s, const int l)
{
int ccr;
s &= 63;
inl_addcycle68(emu68, 2*s);
if (--s < 0) {
ccr = REG68.sr & SR_X;
} else if (s > l) {
ccr = -!!d & SR_V;
d = 0;
} else {
int68_t r = d;
d <<= s;
ccr = ( d >> SIGN_BIT ) & ( SR_X | SR_C );
d <<= 1;
ccr |= -( r != ( (d >> s) >> 1 ) ) & SR_V;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = ( REG68.sr & 0xFF00 ) | ccr;
return d;
}
static inline
int68_t inl_asr68(emu68_t * const emu68, int68_t d, int s, const int l)
{
int ccr;
s &= 63;
inl_addcycle68(emu68, 2*s);
if (--s < 0) {
ccr = REG68.sr & SR_X;
} else if (s > l) {
d >>= SIGN_BIT;
ccr = (int) d & ( SR_C | SR_X );
} else {
const uint68_t m = NRM_MSK(l);
d >>= s;
ccr = -( ( d >> ( SIGN_BIT - l ) ) & 1 ) & ( SR_X | SR_C );
d = ( d >> 1 ) & m;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = (REG68.sr & 0xFF00) | ccr;
return d;
}
static inline
int68_t inl_rol68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr = REG68.sr & (0xFF00 | SR_X);
if (s &= 63) {
const uint68_t m = NRM_MSK(l);
inl_addcycle68(emu68, 2*s);
d = ( ( d << ( s & l ) ) | ( d >> ( -s & l ) ) ) & m;
ccr |= -( ( d >> (SIGN_FIX - l) ) & 1 ) & SR_C;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = ccr;
return d;
}
static inline
int68_t inl_ror68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr = REG68.sr & (0xFF00 | SR_X);
if (s &= 63) {
const uint68_t m = NRM_MSK(l);
inl_addcycle68(emu68, 2*s);
d = ( ( d >> ( s & l ) ) | ( d << ( -s & l ) ) ) & m;
ccr |= ( d >> ( SIGN_BIT - SR_C_BIT ) ) & SR_C;
}
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = ccr;
return d;
}
static inline
int68_t inl_roxl68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr = REG68.sr & ( 0xFF00 | SR_X );
if (s &= 63) {
const uint68_t m = NRM_MSK(l);
inl_addcycle68(emu68, 2*s);
s %= (l+2);
if (--s >= 0) {
uint68_t x, c, r = d;
r <<= s;
c = (ccr >> SR_X_BIT) & 1;
x = r >> SIGN_BIT;
ccr = -(int)x & SR_X;
r <<= 1;
r |= c << ( SIGN_BIT - l + s );
d >>= 1;
d >>= l - s;
d |= r;
d &= m;
}
}
ccr |= (ccr & SR_X) >> (SR_X_BIT - SR_C_BIT);
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = ccr;
return d;
}
static inline
int68_t inl_roxr68(emu68_t * const emu68, uint68_t d, int s, const int l)
{
int ccr = REG68.sr & ( 0xFF00 | SR_X );
s &= 63;
inl_addcycle68(emu68, 2*s);
if (s) {
const uint68_t m = NRM_MSK(l);
s %= l + 2;
if (--s >= 0) {
uint68_t r = d;
uint68_t x, c;
d >>= s;
c = (ccr >> SR_X_BIT) & 1;
x = (d >> (SIGN_BIT-l)) & 1;
ccr = -(int)x & SR_X;
d >>= 1;
d |= c << (SIGN_BIT-s);
r <<= 1;
r <<= l-s;
d |= r;
d &= m;
}
}
ccr |= (ccr & SR_X) >> (SR_X_BIT - SR_C_BIT);
ccr |= -!d & SR_Z;
ccr |= ( d >> ( SIGN_BIT - SR_N_BIT ) ) & SR_N;
REG68.sr = ccr;
return d;
}
#endif