summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/arcompact/arcompact_execute_ops_18_16bit.cpp
blob: 25ab85d8fcdd8ff641e55c2ac5deac4dc8eb9e25 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// license:BSD-3-Clause
// copyright-holders:David Haywood

#include "emu.h"
#include "arcompact_helper.ipp"

// #######################################################################################################################
//                                 IIII I    SSS
// LD_S b,[sp,u7]                  1100 0bbb 000u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_LD_S_b_sp_u7(uint16_t op)   // LD_S b, [SP, u7]
{
	uint8_t breg = common16_get_and_expand_breg(op);
	uint32_t u = common16_get_u5(op);
	uint32_t address = m_regs[REG_SP] + (u << 2);
	m_regs[breg] = READ32(address);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSS
// LDB_S b,[sp,u7]                 1100 0bbb 001u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_LDB_S_b_sp_u7(uint16_t op)
{
	uint8_t breg = common16_get_and_expand_breg(op);
	uint32_t u = common16_get_u5(op);
	uint32_t address = m_regs[REG_SP] + (u << 2);
	m_regs[breg] = READ8(address);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSS
// ST_S b,[sp,u7]                  1100 0bbb 010u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_ST_S_b_sp_u7(uint16_t op)  // ST_S b, [SP, u7]
{
	uint8_t breg = common16_get_and_expand_breg(op);
	uint32_t u = common16_get_u5(op);
	uint32_t address = m_regs[REG_SP] + (u << 2);
	WRITE32(address, m_regs[breg]);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSS
// STB_S b,[sp,u7]                 1100 0bbb 011u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_STB_S_b_sp_u7(uint16_t op)
{
	uint8_t breg = common16_get_and_expand_breg(op);
	uint32_t u = common16_get_u5(op);
	uint32_t address = m_regs[REG_SP] + (u << 2); // still dword aligned u7 despite being a byte write
	WRITE8(address, m_regs[breg] & 0xff); // only write a byte, despite register being 32-bit?
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSS
// ADD_S b,sp,u7                   1100 0bbb 100u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_ADD_S_b_sp_u7(uint16_t op)  // ADD_S b, SP, u7
{
	uint8_t breg = common16_get_and_expand_breg(op);
	uint32_t u = common16_get_u5(op);
	m_regs[breg] = m_regs[REG_SP] + (u << 2);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII Isss SSS
// ADD_S sp,sp,u7                  1100 0000 101u uuuu
// #######################################################################################################################

// op bits remaining for 0x18_05_xx subgroups 0x001f
uint32_t arcompact_device::handleop_ADD_S_sp_sp_u7(uint16_t op)
{
	uint32_t u = common16_get_u5(op);
	m_regs[REG_SP] = m_regs[REG_SP] + (u << 2);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII Isss SSS
// SUB_S sp,sp,u7                  1100 0001 101u uuuu
// #######################################################################################################################

uint32_t arcompact_device::handleop_SUB_S_sp_sp_u7(uint16_t op)
{
	uint32_t u = common16_get_u5(op);
	m_regs[REG_SP] = m_regs[REG_SP] - (u << 2);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSSs ssss
// POP_S b                         1100 0bbb 1100 0001
// #######################################################################################################################

// op bits remaining for 0x18_06_xx subgroups 0x0700
uint32_t arcompact_device::handleop_POP_S_b(uint16_t op) // POP_S b
{
	uint8_t breg = common16_get_and_expand_breg(op);
	m_regs[breg] = READ32(m_regs[REG_SP]);
	m_regs[REG_SP] += 4;
	return m_pc + 2;
}


// #######################################################################################################################
//                                 IIII I    SSSs ssss
// POP_S blink                     1100 0RRR 1101 0001
// #######################################################################################################################

uint32_t arcompact_device::handleop_POP_S_blink(uint16_t op) // POP_S blink
{
	// breg bits are reserved
	m_regs[REG_BLINK] = READ32(m_regs[REG_SP]);
	m_regs[REG_SP] += 4;
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSSs ssss
// PUSH_S b                        1100 0bbb 1110 0001
// #######################################################################################################################

// op bits remaining for 0x18_07_xx subgroups 0x0700
uint32_t arcompact_device::handleop_PUSH_S_b(uint16_t op) // PUSH_S b
{
	uint8_t breg = common16_get_and_expand_breg(op);
	m_regs[REG_SP] -= 4;
	WRITE32(m_regs[REG_SP], m_regs[breg]);
	return m_pc + 2;
}

// #######################################################################################################################
//                                 IIII I    SSSs ssss
// PUSH_S blink                    1100 0RRR 1111 0001
// #######################################################################################################################

uint32_t arcompact_device::handleop_PUSH_S_blink(uint16_t op) // PUSH_S [blink]
{
	// breg bits are reserved
	m_regs[REG_SP] -= 4;
	WRITE32(m_regs[REG_SP], m_regs[REG_BLINK]);
	return m_pc + 2;
}