1 /*
2  * Copyright (c) 2015, Marcos Medeiros
3  * Licensed under BSD 3-clause.
4  */
5 #ifndef TMS34010_SHIFT_H
6 #define TMS34010_SHIFT_H
7 
8 #include "tms34010.h"
9 #include "tms34010_memacc.h"
10 #include "tms34010_defs.h"
11 
12 namespace tms { namespace ops {
13 
rl_k_rd(cpu_state * cpu,word opcode)14 void rl_k_rd(cpu_state *cpu, word opcode)
15 {
16     _st &= ~(ST_C | ST_Z);
17     int k = K;
18     if (k) {
19         const int shift = 32 - k;
20         dword rot = (_rd >> shift) & (0xFFFFFFFF >> shift);
21 
22         _rd <<= k - 1;
23         if (_rd & 0x80000000)
24             _st |= ST_C;
25         _rd <<= 1;
26         _rd |= rot;
27     }
28     if (!_rd)
29         _st |= ST_Z;
30 
31     CONSUME_CYCLES(1);
32 }
33 
34 
rl_rs_rd(cpu_state * cpu,word opcode)35 void rl_rs_rd(cpu_state *cpu, word opcode)
36 {
37     _st &= ~(ST_C | ST_Z);
38     int k = _rs & 0x1F;
39     if (k) {
40         const int shift = 32 - k;
41         dword rot = (_rd >> shift) & (0xFFFFFFFF >> shift);
42 
43         _rd <<= k - 1;
44         if (_rd & 0x80000000)
45             _st |= ST_C;
46         _rd <<= 1;
47         _rd |= rot;
48     }
49     if (!_rd)
50         _st |= ST_Z;
51 
52     CONSUME_CYCLES(1);
53 }
54 
55 
sll_rs_rd(cpu_state * cpu,word opcode)56 void sll_rs_rd(cpu_state *cpu, word opcode)
57 {
58     _st &= ~(ST_C | ST_Z);
59     int k = _rs & 0x1F;
60     if (k) {
61         _rd <<= k - 1;
62         if (_rd & 0x80000000)
63             _st |= ST_C;
64         _rd <<= 1;
65     }
66     if (!_rd)
67         _st |= ST_Z;
68 
69     CONSUME_CYCLES(1);
70 }
71 
sll_k_rd(cpu_state * cpu,word opcode)72 void sll_k_rd(cpu_state *cpu, word opcode)
73 {
74     _st &= ~(ST_C | ST_Z);
75     int k = K;
76     if (k) {
77         _rd <<= k - 1;
78         if (_rd & 0x80000000)
79             _st |= ST_C;
80         _rd <<= 1;
81     }
82     if (!_rd)
83         _st |= ST_Z;
84 
85     CONSUME_CYCLES(1);
86 }
87 
sla_k_rd(cpu_state * cpu,word opcode)88 void sla_k_rd(cpu_state *cpu, word opcode)
89 {
90     _st &= ~(ST_C | ST_V);
91     int k = K;
92     sdword rr = _rd;
93     if (k) {
94         const dword mask = (0xFFFFFFFF << (31 - k)) & 0x7FFFFFFF;
95         dword rr_ = (_rd & 0x80000000) ? _rd ^ mask : _rd;
96         if ((rr_ & mask) != 0)
97             _st |= ST_V;
98 
99         rr <<= (k - 1);
100         if (rr & 0x80000000)
101             _st |= ST_C;
102         rr <<= 1;
103     }
104     _rd = rr;
105     update_zn(_rd);
106 
107     CONSUME_CYCLES(3);
108 }
109 
sla_rs_rd(cpu_state * cpu,word opcode)110 void sla_rs_rd(cpu_state *cpu, word opcode)
111 {
112     _st &= ~(ST_C | ST_V);
113     int k = _rs & 0x1F;
114     sdword rr = _rd;
115     if (k) {
116         const dword mask = (0xFFFFFFFF << (31 - k)) & 0x7FFFFFFF;
117         dword rr_ = (_rd & 0x80000000) ? _rd ^ mask : _rd;
118         if ((rr_ & mask) != 0)
119             _st |= ST_V;
120 
121         rr <<= (k - 1);
122         if (rr & 0x80000000)
123             _st |= ST_C;
124         rr <<= 1;
125     }
126     _rd = rr;
127     update_zn(_rd);
128 
129     CONSUME_CYCLES(3);
130 }
131 
srl_k_rd(cpu_state * cpu,word opcode)132 void srl_k_rd(cpu_state *cpu, word opcode)
133 {
134     _st &= ~(ST_C | ST_Z);
135     int k = (-K) & 0x1F;
136     if (k) {
137         _rd >>= k - 1;
138         if (_rd & 1)
139             _st |= ST_C;
140         _rd >>= 1;
141     }
142     if (!_rd)
143         _st |= ST_Z;
144 
145     CONSUME_CYCLES(1);
146 }
147 
srl_rs_rd(cpu_state * cpu,word opcode)148 void srl_rs_rd(cpu_state *cpu, word opcode)
149 {
150     _st &= ~(ST_C | ST_Z);
151     int k = _rs & 0x1F;
152     if (k) {
153         _rd >>= k - 1;
154         if (_rd & 1)
155             _st |= ST_C;
156         _rd >>= 1;
157     }
158     if (!_rd)
159         _st |= ST_Z;
160 
161     CONSUME_CYCLES(1);
162 }
163 
sra_k_rd(cpu_state * cpu,word opcode)164 void sra_k_rd(cpu_state *cpu, word opcode)
165 {
166     _st &= ~(ST_C | ST_Z);
167     int k = (-K) & 0x1F;
168     sdword rr = _rd;
169     if (k) {
170         rr >>= k - 1;
171         if (rr & 1)
172             _st |= ST_C;
173         rr >>= 1;
174     }
175     _rd = rr;
176     if (!_rd)
177         _st |= ST_Z;
178 
179     CONSUME_CYCLES(1);
180 }
181 
sra_rs_rd(cpu_state * cpu,word opcode)182 void sra_rs_rd(cpu_state *cpu, word opcode)
183 {
184     _st &= ~(ST_C | ST_Z);
185     int k = _rs & 0x1F;
186     sdword rr = _rd;
187     if (k) {
188         rr >>= k - 1;
189         if (rr & 1)
190             _st |= ST_C;
191         rr >>= 1;
192     }
193     _rd = rr;
194     if (!_rd)
195         _st |= ST_Z;
196 
197     CONSUME_CYCLES(1);
198 }
199 
200 
201 } // ops
202 } // tms
203 
204 #endif // TMS34010_SHIFT_H
205