OpenCores
URL https://opencores.org/ocsvn/s80186/s80186/trunk

Subversion Repositories s80186

[/] [s80186/] [trunk/] [tests/] [instructions/] [TestDiv.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
#include <sstream>
19
#include <vector>
20
#include <gtest/gtest.h>
21
 
22
#include "EmulateFixture.h"
23
 
24
template <typename T1, typename T2>
25
struct DivTest {
26
    T1 v1;
27
    T2 v2;
28
    T2 quotient;
29
    T2 remainder;
30
};
31
 
32
using Div8Params =
33
    std::pair<const std::vector<uint8_t>,
34
              const std::vector<struct DivTest<uint16_t, uint8_t>>>;
35
using Div16Params =
36
    std::pair<const std::vector<uint8_t>,
37
              const std::vector<struct DivTest<uint32_t, uint16_t>>>;
38
using IDiv8Params =
39
    std::pair<const std::vector<uint8_t>,
40
              const std::vector<struct DivTest<int16_t, int8_t>>>;
41
using IDiv16Params =
42
    std::pair<const std::vector<uint8_t>,
43
              const std::vector<struct DivTest<int32_t, int16_t>>>;
44
 
45
static const std::vector<struct DivTest<uint16_t, uint8_t>> div8_tests = {
46
    {100, 20, 5, 0}, {500, 250, 2, 0}, {10, 3, 3, 1},
47
};
48
 
49
class DivReg8Test : public EmulateFixture,
50
                    public ::testing::WithParamInterface<Div8Params>
51
{
52
};
53
TEST_P(DivReg8Test, Result)
54
{
55
    auto params = GetParam();
56
    for (auto &t : params.second) {
57
        reset();
58
 
59
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
60
                     std::to_string(static_cast<int>(t.v2)));
61
        write_reg(AX, t.v1);
62
        write_reg(BL, t.v2);
63
        // xDIV bl
64
        set_instruction(params.first);
65
 
66
        emulate();
67
 
68
        ASSERT_EQ(read_reg(AL), t.quotient);
69
        ASSERT_EQ(read_reg(AH), t.remainder);
70
    }
71
}
72
INSTANTIATE_TEST_CASE_P(Div,
73
                        DivReg8Test,
74
                        ::testing::Values(Div8Params({0xf6, 0xf3},
75
                                                     div8_tests)));
76
 
77
class DivMem8Test : public EmulateFixture,
78
                    public ::testing::WithParamInterface<Div8Params>
79
{
80
};
81
TEST_P(DivMem8Test, Result)
82
{
83
    auto params = GetParam();
84
    for (auto &t : params.second) {
85
        reset();
86
 
87
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
88
                     std::to_string(static_cast<int>(t.v2)));
89
        write_reg(AX, t.v1);
90
        write_reg(BX, 0x100);
91
        write_mem8(0x100, t.v2);
92
 
93
        // xDIV byte [bx]
94
        set_instruction(params.first);
95
 
96
        emulate();
97
 
98
        ASSERT_EQ(read_reg(AL), t.quotient);
99
        ASSERT_EQ(read_reg(AH), t.remainder);
100
    }
101
}
102
INSTANTIATE_TEST_CASE_P(Div,
103
                        DivMem8Test,
104
                        ::testing::Values(Div8Params({0xf6, 0x37},
105
                                                     div8_tests)));
106
 
107
static const std::vector<struct DivTest<uint32_t, uint16_t>> div16_tests = {
108
    {1000, 200, 5, 0}, {500, 250, 2, 0}, {1000, 3, 333, 1},
109
        {0x109, 0xe90b, 0, 265},
110
};
111
 
112
class DivReg16Test : public EmulateFixture,
113
                     public ::testing::WithParamInterface<Div16Params>
114
{
115
};
116
TEST_P(DivReg16Test, Result)
117
{
118
    auto params = GetParam();
119
    for (auto &t : params.second) {
120
        reset();
121
 
122
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
123
                     std::to_string(static_cast<int>(t.v2)));
124
        write_reg(DX, (t.v1 >> 16) & 0xffff);
125
        write_reg(AX, t.v1);
126
        write_reg(BX, t.v2);
127
        // xDIV bx
128
        set_instruction(params.first);
129
 
130
        emulate();
131
 
132
        ASSERT_EQ(read_reg(AX), t.quotient);
133
        ASSERT_EQ(read_reg(DX), t.remainder);
134
    }
135
}
136
INSTANTIATE_TEST_CASE_P(Div,
137
                        DivReg16Test,
138
                        ::testing::Values(Div16Params({0xf7, 0xf3},
139
                                                      div16_tests)));
140
 
141
class DivMem16Test : public EmulateFixture,
142
                     public ::testing::WithParamInterface<Div16Params>
143
{
144
};
145
TEST_P(DivMem16Test, Result)
146
{
147
    auto params = GetParam();
148
    for (auto &t : params.second) {
149
        reset();
150
 
151
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
152
                     std::to_string(static_cast<int>(t.v2)));
153
        write_reg(DX, (t.v1 >> 16) & 0xffff);
154
        write_reg(AX, t.v1);
155
        write_reg(BX, 0x100);
156
        write_mem16(0x100, t.v2);
157
 
158
        // xDIV word [bx]
159
        set_instruction(params.first);
160
 
161
        emulate();
162
 
163
        ASSERT_EQ(read_reg(AX), t.quotient);
164
        ASSERT_EQ(read_reg(DX), t.remainder);
165
    }
166
}
167
INSTANTIATE_TEST_CASE_P(Div,
168
                        DivMem16Test,
169
                        ::testing::Values(Div16Params({0xf7, 0x37},
170
                                                      div16_tests)));
171
 
172
static const std::vector<struct DivTest<int16_t, int8_t>> idiv8_tests = {
173
    {
174
        250, 10, 25, 0,
175
    },
176
        {
177
            10, 3, 3, 1,
178
        },
179
        {
180
            10, -3, -3, 1,
181
        },
182
        {
183
            -10, -3, 3, -1,
184
        },
185
        {
186
            -10, 3, -3, -1,
187
        },
188
        {
189
            254, 2, 127, 0,
190
        },
191
};
192
 
193
class IDivReg8Test : public EmulateFixture,
194
                     public ::testing::WithParamInterface<IDiv8Params>
195
{
196
};
197
TEST_P(IDivReg8Test, Result)
198
{
199
    auto params = GetParam();
200
    for (auto &t : params.second) {
201
        reset();
202
 
203
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
204
                     std::to_string(static_cast<int>(t.v2)));
205
        write_reg(AX, t.v1);
206
        write_reg(BL, t.v2);
207
        // xDIV bl
208
        set_instruction(params.first);
209
 
210
        emulate();
211
 
212
        EXPECT_EQ(static_cast<int8_t>(read_reg(AL)), t.quotient);
213
        EXPECT_EQ(static_cast<int8_t>(read_reg(AH)), t.remainder);
214
    }
215
}
216
INSTANTIATE_TEST_CASE_P(IDiv,
217
                        IDivReg8Test,
218
                        ::testing::Values(IDiv8Params({0xf6, 0xfb},
219
                                                      idiv8_tests)));
220
 
221
class IDivMem8Test : public EmulateFixture,
222
                     public ::testing::WithParamInterface<IDiv8Params>
223
{
224
};
225
TEST_P(IDivMem8Test, Result)
226
{
227
    auto params = GetParam();
228
    for (auto &t : params.second) {
229
        reset();
230
 
231
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
232
                     std::to_string(static_cast<int>(t.v2)));
233
        write_reg(AX, t.v1);
234
        write_reg(BX, 0x100);
235
        write_mem8(0x100, t.v2);
236
 
237
        // xDIV byte [bx]
238
        set_instruction(params.first);
239
 
240
        emulate();
241
 
242
        ASSERT_EQ(static_cast<int8_t>(read_reg(AL)), t.quotient);
243
        ASSERT_EQ(static_cast<int8_t>(read_reg(AH)), t.remainder);
244
    }
245
}
246
INSTANTIATE_TEST_CASE_P(IDiv,
247
                        IDivMem8Test,
248
                        ::testing::Values(IDiv8Params({0xf6, 0x3f},
249
                                                      idiv8_tests)));
250
 
251
static const std::vector<struct DivTest<int32_t, int16_t>> idiv16_tests = {
252
    {10, 3, 3, 1}, {10, -3, -3, 1}, {-10, -3, 3, -1}, {-10, 3, -3, -1},
253
        {65534, 2, 32767, 0},
254
};
255
 
256
class IDivReg16Test : public EmulateFixture,
257
                      public ::testing::WithParamInterface<IDiv16Params>
258
{
259
};
260
TEST_P(IDivReg16Test, Result)
261
{
262
    auto params = GetParam();
263
    for (auto &t : params.second) {
264
        reset();
265
 
266
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
267
                     std::to_string(static_cast<int>(t.v2)));
268
        write_reg(DX, (t.v1 >> 16) & 0xffff);
269
        write_reg(AX, t.v1);
270
        write_reg(BX, t.v2);
271
        // xDIV bx
272
        set_instruction(params.first);
273
 
274
        emulate();
275
 
276
        EXPECT_EQ(static_cast<int16_t>(read_reg(AX)), t.quotient);
277
        EXPECT_EQ(static_cast<int16_t>(read_reg(DX)), t.remainder);
278
    }
279
}
280
INSTANTIATE_TEST_CASE_P(IDiv,
281
                        IDivReg16Test,
282
                        ::testing::Values(IDiv16Params({0xf7, 0xfb},
283
                                                       idiv16_tests)));
284
 
285
class IDivMem16Test : public EmulateFixture,
286
                      public ::testing::WithParamInterface<IDiv16Params>
287
{
288
};
289
TEST_P(IDivMem16Test, Result)
290
{
291
    auto params = GetParam();
292
    for (auto &t : params.second) {
293
        reset();
294
 
295
        SCOPED_TRACE(std::to_string(static_cast<int>(t.v1)) + " / " +
296
                     std::to_string(static_cast<int>(t.v2)));
297
        write_reg(DX, (t.v1 >> 16) & 0xffff);
298
        write_reg(AX, t.v1);
299
        write_reg(BX, 0x100);
300
        write_mem16(0x100, t.v2);
301
 
302
        // xDIV word [bx]
303
        set_instruction(params.first);
304
 
305
        emulate();
306
 
307
        ASSERT_EQ(static_cast<int16_t>(read_reg(AX)), t.quotient);
308
        ASSERT_EQ(static_cast<int16_t>(read_reg(DX)), t.remainder);
309
    }
310
}
311
INSTANTIATE_TEST_CASE_P(IDiv,
312
                        IDivMem16Test,
313
                        ::testing::Values(IDiv16Params({0xf7, 0x3f},
314
                                                       idiv16_tests)));

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.