Initial release of CAR
This commit is contained in:
216
operations.c
Normal file
216
operations.c
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Source file for register operations.
|
||||
*
|
||||
* CAR (Cool ARM Ripoff) copyright (c) 2026 David J Goeke. All rights reserved.
|
||||
* Unauthorized (re)distribution is prohibited.
|
||||
*/
|
||||
|
||||
|
||||
#include "include/defs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_OP(add)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] + state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(sub)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] - state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(mul)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] * state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(divide)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
if (src1 == 0 || src2 == 0)
|
||||
{
|
||||
state->flags |= FLAG_DIVISION_ERROR;
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] / state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(modulus)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
if (src1 == 0 || src2 == 0)
|
||||
{
|
||||
state->flags |= FLAG_DIVISION_ERROR;
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] % state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(shl)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] << state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(shr)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] >> state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(ahr)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = (uint32_t) ((int32_t) state->gprs[src1]) >> state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
static uint32_t rotr32(uint32_t x, uint32_t n)
|
||||
{
|
||||
n &= 31; // Ensure 0 <= n < 32
|
||||
return (x >> n) | (x << ((32 - n) & 31));
|
||||
}
|
||||
|
||||
DEFINE_OP(ror)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = rotr32(state->gprs[src1], state->gprs[src2]);
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(band)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] & state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(bor)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] | state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(bxor)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
state->gprs[dest] = state->gprs[src1] ^ state->gprs[src2];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(bnot)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t dest = i.dest;
|
||||
uint8_t src1 = i.src1;
|
||||
|
||||
state->gprs[dest] = ~(state->gprs[src1]);
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
|
||||
DEFINE_OP(xchg)
|
||||
{
|
||||
register_instruction_t i = convert_raw2register(ri);
|
||||
|
||||
uint8_t src1 = i.src1;
|
||||
uint8_t src2 = i.src2;
|
||||
|
||||
// Truthfully we could use XORs here, but it's not really faster, so there is no real point,
|
||||
// along with the fact that if both values are the same the result is zeroed out.
|
||||
|
||||
uint8_t temp = src1;
|
||||
|
||||
state->gprs[src1] = state->gprs[src2];
|
||||
state->gprs[src2] = state->gprs[temp];
|
||||
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
Reference in New Issue
Block a user