sh-dis/c/operations.h
Zack Buhman 8a300ba4c6 initial SH4 emulator implementation in C
This currently only implements the SH2 instructions.
2024-04-22 20:53:36 +08:00

132 lines
2.0 KiB
C

#pragma once
#include <stdint.h>
#include <assert.h>
//
// sign_extend
//
static inline int32_t sign_extend(uint32_t x, uint32_t b)
{
const uint32_t m = 1UL << (b - 1);
x = x & ((1UL << b) - 1);
const int32_t r = (x ^ m) - m;
return r;
}
static inline int64_t sign_extend64(uint64_t x)
{
return (int64_t)x;
}
static inline int32_t sign_extend32(uint32_t x)
{
return (int32_t)x;
}
static inline int32_t sign_extend16(uint32_t x)
{
return sign_extend(x, 16);
}
static inline int32_t sign_extend12(uint32_t x)
{
return sign_extend(x, 12);
}
static inline int32_t sign_extend8(uint32_t x)
{
return sign_extend(x, 8);
}
//
// zero_extend
//
static inline uint32_t zero_extend(uint32_t x, uint32_t b)
{
x = x & ((1ULL << b) - 1);
return x;
}
static inline uint32_t zero_extend32(uint32_t x)
{
return (uint32_t)x;
}
static inline uint32_t zero_extend16(uint32_t x)
{
return zero_extend(x, 16);
}
static inline uint32_t zero_extend8(uint32_t x)
{
return zero_extend(x, 8);
}
static inline uint32_t zero_extend4(uint32_t x)
{
return zero_extend(x, 4);
}
static inline uint32_t zero_extend1(uint32_t x)
{
return zero_extend(x, 1);
}
//
// signed_saturate
//
static inline uint64_t signed_saturate(uint64_t x, uint32_t b)
{
const int64_t upper = (1LL << (b - 1)) - 1;
const int64_t lower = -(1LL << (b - 1));
static_assert(-(1LL << (48 - 1)) < 0);
if (x > upper)
return upper;
else if (x < lower)
return lower;
else
return x;
}
static inline uint64_t signed_saturate48(uint64_t x)
{
return signed_saturate(x, 48);
}
static inline uint32_t signed_saturate32(uint32_t x)
{
return signed_saturate(x, 32);
}
//
// "convenience" functions
//
static inline uint32_t _register(uint32_t x)
{
return zero_extend(x, 32);
}
static inline uint32_t bit(uint32_t x)
{
return zero_extend(x, 1);
}
//
// "operations"
//
static inline int32_t unary_int(int64_t x)
{
return x != 0;
}
static inline int64_t bit_extract(int64_t n, int64_t b, int64_t m)
{
return (n >> b) & ((1 << m) - 1);
}