compiler/
lib/
examples/
std/
arch/
rv64/
asm/
image/
shared/
asm.rad
24.8 KiB
atomicTests.rad
5.0 KiB
atomics.rad
3.6 KiB
bounds.rad
21.0 KiB
decode.rad
15.2 KiB
emit.rad
33.2 KiB
encode.rad
22.0 KiB
image.rad
4.5 KiB
isel.rad
52.1 KiB
printer.rad
13.9 KiB
shared.rad
16.8 KiB
tests.rad
17.2 KiB
rv64.rad
17.5 KiB
char/
collections/
lang/
sys/
arch.rad
68 B
char.rad
855 B
collections.rad
39 B
fmt.rad
8.3 KiB
intrinsics.rad
467 B
io.rad
1.7 KiB
lang.rad
276 B
mem.rad
2.3 KiB
sys.rad
179 B
testing.rad
2.4 KiB
tests.rad
15.7 KiB
vec.rad
3.2 KiB
std.rad
281 B
scripts/
seed/
sublime/
test/
vim/
.gitignore
336 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
5.4 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.5 KiB
std.lib.test
662 B
lib/std/arch/rv64/tests.rad
raw
| 1 | //! RV64I+M instruction encoding tests. |
| 2 | //! |
| 3 | //! These tests verify that instruction encodings match the RISC-V specification |
| 4 | //! by comparing against known-good values. |
| 5 | |
| 6 | use std::testing; |
| 7 | use std::lang::alloc; |
| 8 | use std::collections::dict; |
| 9 | |
| 10 | use super::encode; |
| 11 | use super::asm; |
| 12 | |
| 13 | static ASSEMBLY_ARENA_STORAGE: [u8; 16777216] = [0; 16777216]; |
| 14 | static ASSEMBLY_TEXT_STORAGE: [u32; 2] = [0; 2]; |
| 15 | |
| 16 | /// Helper to check encoding equals expected value. |
| 17 | fn expectEncoding(actual: u32, expected: u32) throws (testing::TestError) { |
| 18 | try testing::expect(actual == expected); |
| 19 | } |
| 20 | |
| 21 | @test unsafe fn testAddAssemblyExportsOnlyGlobalTextSymbols() throws (testing::TestError) { |
| 22 | let mut arena = alloc::new(&mut ASSEMBLY_ARENA_STORAGE[..]); |
| 23 | let symbols = try alloc::allocSlice(&mut arena, @sizeOf(asm::Symbol), @alignOf(asm::Symbol), 2) catch { |
| 24 | throw testing::TestError::Failed; |
| 25 | }; |
| 26 | let symbolSlice = symbols as *mut [asm::Symbol]; |
| 27 | set symbolSlice[0] = asm::Symbol { |
| 28 | name: "local", |
| 29 | section: asm::Section::Text, |
| 30 | offset: 0, |
| 31 | isExported: false, |
| 32 | }; |
| 33 | set symbolSlice[1] = asm::Symbol { |
| 34 | name: "exported", |
| 35 | section: asm::Section::Text, |
| 36 | offset: super::INSTR_SIZE, |
| 37 | isExported: true, |
| 38 | }; |
| 39 | |
| 40 | let mut generator = try! super::beginProgram( |
| 41 | super::ProgramOptions { entryPatch: super::EntryPatch::None, debug: false, placement: super::image::Placement::Hosted }, |
| 42 | &mut arena |
| 43 | ); |
| 44 | super::addAssembly( |
| 45 | &mut generator, |
| 46 | asm::Program { |
| 47 | text: &ASSEMBLY_TEXT_STORAGE[..], |
| 48 | data: &[], |
| 49 | symbols: symbolSlice, |
| 50 | externalFixups: &[], |
| 51 | } |
| 52 | ); |
| 53 | |
| 54 | try testing::expect(dict::get(&generator.e.labels.funcs, "local") == nil); |
| 55 | let exportedOffset = dict::get(&generator.e.labels.funcs, "exported") else { |
| 56 | throw testing::TestError::Failed; |
| 57 | }; |
| 58 | try testing::expect(exportedOffset == super::INSTR_SIZE); |
| 59 | } |
| 60 | |
| 61 | /////////////////////// |
| 62 | // R-type ALU tests // |
| 63 | /////////////////////// |
| 64 | |
| 65 | @test fn testEncodeAdd() throws (testing::TestError) { |
| 66 | let enc = encode::add(super::reg(1), super::reg(2), super::reg(3)); |
| 67 | try expectEncoding(enc, 0x003100B3); |
| 68 | } |
| 69 | |
| 70 | @test fn testEncodeSub() throws (testing::TestError) { |
| 71 | let enc = encode::sub(super::reg(5), super::reg(6), super::reg(7)); |
| 72 | try expectEncoding(enc, 0x407302B3); |
| 73 | } |
| 74 | |
| 75 | @test fn testEncodeSll() throws (testing::TestError) { |
| 76 | let enc = encode::sll(super::reg(1), super::reg(2), super::reg(3)); |
| 77 | try expectEncoding(enc, 0x003110B3); |
| 78 | } |
| 79 | |
| 80 | @test fn testEncodeSlt() throws (testing::TestError) { |
| 81 | let enc = encode::slt(super::reg(1), super::reg(2), super::reg(3)); |
| 82 | try expectEncoding(enc, 0x003120B3); |
| 83 | } |
| 84 | |
| 85 | @test fn testEncodeSltu() throws (testing::TestError) { |
| 86 | let enc = encode::sltu(super::reg(1), super::reg(2), super::reg(3)); |
| 87 | try expectEncoding(enc, 0x003130B3); |
| 88 | } |
| 89 | |
| 90 | @test fn testEncodeXor() throws (testing::TestError) { |
| 91 | let enc = encode::xor(super::reg(1), super::reg(2), super::reg(3)); |
| 92 | try expectEncoding(enc, 0x003140B3); |
| 93 | } |
| 94 | |
| 95 | @test fn testEncodeSrl() throws (testing::TestError) { |
| 96 | let enc = encode::srl(super::reg(1), super::reg(2), super::reg(3)); |
| 97 | try expectEncoding(enc, 0x003150B3); |
| 98 | } |
| 99 | |
| 100 | @test fn testEncodeSra() throws (testing::TestError) { |
| 101 | let enc = encode::sra(super::reg(1), super::reg(2), super::reg(3)); |
| 102 | try expectEncoding(enc, 0x403150B3); |
| 103 | } |
| 104 | |
| 105 | @test fn testEncodeOr() throws (testing::TestError) { |
| 106 | let enc = encode::or_(super::reg(1), super::reg(2), super::reg(3)); |
| 107 | try expectEncoding(enc, 0x003160B3); |
| 108 | } |
| 109 | |
| 110 | @test fn testEncodeAnd() throws (testing::TestError) { |
| 111 | let enc = encode::and_(super::reg(1), super::reg(2), super::reg(3)); |
| 112 | try expectEncoding(enc, 0x003170B3); |
| 113 | } |
| 114 | |
| 115 | /////////////////////// |
| 116 | // I-type ALU tests // |
| 117 | /////////////////////// |
| 118 | |
| 119 | @test fn testEncodeAddi() throws (testing::TestError) { |
| 120 | let enc = encode::addi(super::reg(1), super::ZERO, 42); |
| 121 | try expectEncoding(enc, 0x02A00093); |
| 122 | } |
| 123 | |
| 124 | @test fn testEncodeAddiNegative() throws (testing::TestError) { |
| 125 | let enc = encode::addi(super::reg(1), super::ZERO, -1); |
| 126 | try expectEncoding(enc, 0xFFF00093); |
| 127 | } |
| 128 | |
| 129 | @test fn testEncodeSlti() throws (testing::TestError) { |
| 130 | let enc = encode::slti(super::reg(1), super::reg(2), 100); |
| 131 | try expectEncoding(enc, 0x06412093); |
| 132 | } |
| 133 | |
| 134 | @test fn testEncodeSltiu() throws (testing::TestError) { |
| 135 | let enc = encode::sltiu(super::reg(1), super::reg(2), 100); |
| 136 | try expectEncoding(enc, 0x06413093); |
| 137 | } |
| 138 | |
| 139 | @test fn testEncodeXori() throws (testing::TestError) { |
| 140 | let enc = encode::xori(super::reg(1), super::reg(2), 0xFF); |
| 141 | try expectEncoding(enc, 0x0FF14093); |
| 142 | } |
| 143 | |
| 144 | @test fn testEncodeOri() throws (testing::TestError) { |
| 145 | let enc = encode::ori(super::reg(1), super::reg(2), 0xFF); |
| 146 | try expectEncoding(enc, 0x0FF16093); |
| 147 | } |
| 148 | |
| 149 | @test fn testEncodeAndi() throws (testing::TestError) { |
| 150 | let enc = encode::andi(super::reg(1), super::reg(2), 0xFF); |
| 151 | try expectEncoding(enc, 0x0FF17093); |
| 152 | } |
| 153 | |
| 154 | @test fn testEncodeSlli() throws (testing::TestError) { |
| 155 | let enc = encode::slli(super::reg(1), super::reg(2), 5); |
| 156 | try expectEncoding(enc, 0x00511093); |
| 157 | } |
| 158 | |
| 159 | @test fn testEncodeSrli() throws (testing::TestError) { |
| 160 | let enc = encode::srli(super::reg(1), super::reg(2), 5); |
| 161 | try expectEncoding(enc, 0x00515093); |
| 162 | } |
| 163 | |
| 164 | @test fn testEncodeSrai() throws (testing::TestError) { |
| 165 | let enc = encode::srai(super::reg(1), super::reg(2), 5); |
| 166 | try expectEncoding(enc, 0x40515093); |
| 167 | } |
| 168 | |
| 169 | ////////////////// |
| 170 | // Load tests // |
| 171 | ////////////////// |
| 172 | |
| 173 | @test fn testEncodeLb() throws (testing::TestError) { |
| 174 | let enc = encode::lb(super::reg(1), super::reg(2), 8); |
| 175 | try expectEncoding(enc, 0x00810083); |
| 176 | } |
| 177 | |
| 178 | @test fn testEncodeLh() throws (testing::TestError) { |
| 179 | let enc = encode::lh(super::reg(1), super::reg(2), 8); |
| 180 | try expectEncoding(enc, 0x00811083); |
| 181 | } |
| 182 | |
| 183 | @test fn testEncodeLw() throws (testing::TestError) { |
| 184 | let enc = encode::lw(super::reg(1), super::reg(2), 8); |
| 185 | try expectEncoding(enc, 0x00812083); |
| 186 | } |
| 187 | |
| 188 | @test fn testEncodeLbu() throws (testing::TestError) { |
| 189 | let enc = encode::lbu(super::reg(1), super::reg(2), 8); |
| 190 | try expectEncoding(enc, 0x00814083); |
| 191 | } |
| 192 | |
| 193 | @test fn testEncodeLhu() throws (testing::TestError) { |
| 194 | let enc = encode::lhu(super::reg(1), super::reg(2), 8); |
| 195 | try expectEncoding(enc, 0x00815083); |
| 196 | } |
| 197 | |
| 198 | @test fn testEncodeLwu() throws (testing::TestError) { |
| 199 | let enc = encode::lwu(super::reg(1), super::reg(2), 8); |
| 200 | try expectEncoding(enc, 0x00816083); |
| 201 | } |
| 202 | |
| 203 | @test fn testEncodeLd() throws (testing::TestError) { |
| 204 | let enc = encode::ld(super::reg(1), super::reg(2), 8); |
| 205 | try expectEncoding(enc, 0x00813083); |
| 206 | } |
| 207 | |
| 208 | ////////////////// |
| 209 | // Store tests // |
| 210 | ////////////////// |
| 211 | |
| 212 | @test fn testEncodeSb() throws (testing::TestError) { |
| 213 | let enc = encode::sb(super::reg(3), super::reg(2), 8); |
| 214 | try expectEncoding(enc, 0x00310423); |
| 215 | } |
| 216 | |
| 217 | @test fn testEncodeSh() throws (testing::TestError) { |
| 218 | let enc = encode::sh(super::reg(3), super::reg(2), 8); |
| 219 | try expectEncoding(enc, 0x00311423); |
| 220 | } |
| 221 | |
| 222 | @test fn testEncodeSw() throws (testing::TestError) { |
| 223 | let enc = encode::sw(super::reg(3), super::reg(2), 8); |
| 224 | try expectEncoding(enc, 0x00312423); |
| 225 | } |
| 226 | |
| 227 | @test fn testEncodeSd() throws (testing::TestError) { |
| 228 | let enc = encode::sd(super::reg(3), super::reg(2), 8); |
| 229 | try expectEncoding(enc, 0x00313423); |
| 230 | } |
| 231 | |
| 232 | @test fn testEncodeSwNegativeOffset() throws (testing::TestError) { |
| 233 | let enc = encode::sw(super::reg(3), super::reg(2), -4); |
| 234 | try expectEncoding(enc, 0xFE312E23); |
| 235 | } |
| 236 | |
| 237 | ////////////////// |
| 238 | // Branch tests // |
| 239 | ////////////////// |
| 240 | |
| 241 | @test fn testEncodeBeq() throws (testing::TestError) { |
| 242 | let enc = encode::beq(super::reg(1), super::reg(2), 8); |
| 243 | try expectEncoding(enc, 0x00208463); |
| 244 | } |
| 245 | |
| 246 | @test fn testEncodeBne() throws (testing::TestError) { |
| 247 | let enc = encode::bne(super::reg(1), super::reg(2), 8); |
| 248 | try expectEncoding(enc, 0x00209463); |
| 249 | } |
| 250 | |
| 251 | @test fn testEncodeBlt() throws (testing::TestError) { |
| 252 | let enc = encode::blt(super::reg(1), super::reg(2), 8); |
| 253 | try expectEncoding(enc, 0x0020C463); |
| 254 | } |
| 255 | |
| 256 | @test fn testEncodeBge() throws (testing::TestError) { |
| 257 | let enc = encode::bge(super::reg(1), super::reg(2), 8); |
| 258 | try expectEncoding(enc, 0x0020D463); |
| 259 | } |
| 260 | |
| 261 | @test fn testEncodeBltu() throws (testing::TestError) { |
| 262 | let enc = encode::bltu(super::reg(1), super::reg(2), 8); |
| 263 | try expectEncoding(enc, 0x0020E463); |
| 264 | } |
| 265 | |
| 266 | @test fn testEncodeBgeu() throws (testing::TestError) { |
| 267 | let enc = encode::bgeu(super::reg(1), super::reg(2), 8); |
| 268 | try expectEncoding(enc, 0x0020F463); |
| 269 | } |
| 270 | |
| 271 | @test fn testEncodeBranchNegative() throws (testing::TestError) { |
| 272 | let enc = encode::beq(super::reg(1), super::reg(2), -8); |
| 273 | try expectEncoding(enc, 0xFE208CE3); |
| 274 | } |
| 275 | |
| 276 | ////////////////// |
| 277 | // Jump tests // |
| 278 | ////////////////// |
| 279 | |
| 280 | @test fn testEncodeJal() throws (testing::TestError) { |
| 281 | let enc = encode::jal(super::reg(1), 8); |
| 282 | try expectEncoding(enc, 0x008000EF); |
| 283 | } |
| 284 | |
| 285 | @test fn testEncodeJalr() throws (testing::TestError) { |
| 286 | let enc = encode::jalr(super::reg(1), super::reg(2), 8); |
| 287 | try expectEncoding(enc, 0x008100E7); |
| 288 | } |
| 289 | |
| 290 | /////////////////////////// |
| 291 | // Upper immediate tests // |
| 292 | /////////////////////////// |
| 293 | |
| 294 | @test fn testEncodeLui() throws (testing::TestError) { |
| 295 | let enc = encode::lui(super::reg(1), 0x12345); |
| 296 | try expectEncoding(enc, 0x123450B7); |
| 297 | } |
| 298 | |
| 299 | @test fn testEncodeAuipc() throws (testing::TestError) { |
| 300 | let enc = encode::auipc(super::reg(1), 0x12345); |
| 301 | try expectEncoding(enc, 0x12345097); |
| 302 | } |
| 303 | |
| 304 | ////////////////// |
| 305 | // System tests // |
| 306 | ////////////////// |
| 307 | |
| 308 | @test fn testEncodeEcall() throws (testing::TestError) { |
| 309 | let enc = encode::ecall(); |
| 310 | try expectEncoding(enc, 0x00000073); |
| 311 | } |
| 312 | |
| 313 | @test fn testEncodeEbreak() throws (testing::TestError) { |
| 314 | let enc = encode::ebreak(); |
| 315 | try expectEncoding(enc, 0x00100073); |
| 316 | } |
| 317 | |
| 318 | ///////////////////// |
| 319 | // M extension tests |
| 320 | ///////////////////// |
| 321 | |
| 322 | @test fn testEncodeMul() throws (testing::TestError) { |
| 323 | let enc = encode::mul(super::reg(1), super::reg(2), super::reg(3)); |
| 324 | try expectEncoding(enc, 0x023100B3); |
| 325 | } |
| 326 | |
| 327 | @test fn testEncodeMulh() throws (testing::TestError) { |
| 328 | let enc = encode::mulh(super::reg(1), super::reg(2), super::reg(3)); |
| 329 | try expectEncoding(enc, 0x023110B3); |
| 330 | } |
| 331 | |
| 332 | @test fn testEncodeMulhsu() throws (testing::TestError) { |
| 333 | let enc = encode::mulhsu(super::reg(1), super::reg(2), super::reg(3)); |
| 334 | try expectEncoding(enc, 0x023120B3); |
| 335 | } |
| 336 | |
| 337 | @test fn testEncodeMulhu() throws (testing::TestError) { |
| 338 | let enc = encode::mulhu(super::reg(1), super::reg(2), super::reg(3)); |
| 339 | try expectEncoding(enc, 0x023130B3); |
| 340 | } |
| 341 | |
| 342 | @test fn testEncodeDiv() throws (testing::TestError) { |
| 343 | let enc = encode::div(super::reg(1), super::reg(2), super::reg(3)); |
| 344 | try expectEncoding(enc, 0x023140B3); |
| 345 | } |
| 346 | |
| 347 | @test fn testEncodeDivu() throws (testing::TestError) { |
| 348 | let enc = encode::divu(super::reg(1), super::reg(2), super::reg(3)); |
| 349 | try expectEncoding(enc, 0x023150B3); |
| 350 | } |
| 351 | |
| 352 | @test fn testEncodeRem() throws (testing::TestError) { |
| 353 | let enc = encode::rem(super::reg(1), super::reg(2), super::reg(3)); |
| 354 | try expectEncoding(enc, 0x023160B3); |
| 355 | } |
| 356 | |
| 357 | @test fn testEncodeRemu() throws (testing::TestError) { |
| 358 | let enc = encode::remu(super::reg(1), super::reg(2), super::reg(3)); |
| 359 | try expectEncoding(enc, 0x023170B3); |
| 360 | } |
| 361 | |
| 362 | //////////////////////////// |
| 363 | // RV64 Word operation tests |
| 364 | //////////////////////////// |
| 365 | |
| 366 | @test fn testEncodeAddiw() throws (testing::TestError) { |
| 367 | let enc = encode::addiw(super::reg(1), super::reg(2), 42); |
| 368 | try expectEncoding(enc, 0x02A1009B); |
| 369 | } |
| 370 | |
| 371 | @test fn testEncodeSlliw() throws (testing::TestError) { |
| 372 | let enc = encode::slliw(super::reg(1), super::reg(2), 5); |
| 373 | try expectEncoding(enc, 0x0051109B); |
| 374 | } |
| 375 | |
| 376 | @test fn testEncodeSrliw() throws (testing::TestError) { |
| 377 | let enc = encode::srliw(super::reg(1), super::reg(2), 5); |
| 378 | try expectEncoding(enc, 0x0051509B); |
| 379 | } |
| 380 | |
| 381 | @test fn testEncodeSraiw() throws (testing::TestError) { |
| 382 | let enc = encode::sraiw(super::reg(1), super::reg(2), 5); |
| 383 | try expectEncoding(enc, 0x4051509B); |
| 384 | } |
| 385 | |
| 386 | @test fn testEncodeAddw() throws (testing::TestError) { |
| 387 | let enc = encode::addw(super::reg(1), super::reg(2), super::reg(3)); |
| 388 | try expectEncoding(enc, 0x003100BB); |
| 389 | } |
| 390 | |
| 391 | @test fn testEncodeSubw() throws (testing::TestError) { |
| 392 | let enc = encode::subw(super::reg(1), super::reg(2), super::reg(3)); |
| 393 | try expectEncoding(enc, 0x403100BB); |
| 394 | } |
| 395 | |
| 396 | @test fn testEncodeSllw() throws (testing::TestError) { |
| 397 | let enc = encode::sllw(super::reg(1), super::reg(2), super::reg(3)); |
| 398 | try expectEncoding(enc, 0x003110BB); |
| 399 | } |
| 400 | |
| 401 | @test fn testEncodeSrlw() throws (testing::TestError) { |
| 402 | let enc = encode::srlw(super::reg(1), super::reg(2), super::reg(3)); |
| 403 | try expectEncoding(enc, 0x003150BB); |
| 404 | } |
| 405 | |
| 406 | @test fn testEncodeSraw() throws (testing::TestError) { |
| 407 | let enc = encode::sraw(super::reg(1), super::reg(2), super::reg(3)); |
| 408 | try expectEncoding(enc, 0x403150BB); |
| 409 | } |
| 410 | |
| 411 | @test fn testEncodeMulw() throws (testing::TestError) { |
| 412 | let enc = encode::mulw(super::reg(1), super::reg(2), super::reg(3)); |
| 413 | try expectEncoding(enc, 0x023100BB); |
| 414 | } |
| 415 | |
| 416 | @test fn testEncodeDivw() throws (testing::TestError) { |
| 417 | let enc = encode::divw(super::reg(1), super::reg(2), super::reg(3)); |
| 418 | try expectEncoding(enc, 0x023140BB); |
| 419 | } |
| 420 | |
| 421 | @test fn testEncodeDivuw() throws (testing::TestError) { |
| 422 | let enc = encode::divuw(super::reg(1), super::reg(2), super::reg(3)); |
| 423 | try expectEncoding(enc, 0x023150BB); |
| 424 | } |
| 425 | |
| 426 | @test fn testEncodeRemw() throws (testing::TestError) { |
| 427 | let enc = encode::remw(super::reg(1), super::reg(2), super::reg(3)); |
| 428 | try expectEncoding(enc, 0x023160BB); |
| 429 | } |
| 430 | |
| 431 | @test fn testEncodeRemuw() throws (testing::TestError) { |
| 432 | let enc = encode::remuw(super::reg(1), super::reg(2), super::reg(3)); |
| 433 | try expectEncoding(enc, 0x023170BB); |
| 434 | } |
| 435 | |
| 436 | ///////////////////////////////// |
| 437 | // RV64 6-bit shift amount tests |
| 438 | ///////////////////////////////// |
| 439 | |
| 440 | @test fn testEncodeSlli64() throws (testing::TestError) { |
| 441 | let enc = encode::slli(super::reg(1), super::reg(2), 32); |
| 442 | try expectEncoding(enc, 0x02011093); |
| 443 | } |
| 444 | |
| 445 | @test fn testEncodeSrli64() throws (testing::TestError) { |
| 446 | let enc = encode::srli(super::reg(1), super::reg(2), 32); |
| 447 | try expectEncoding(enc, 0x02015093); |
| 448 | } |
| 449 | |
| 450 | @test fn testEncodeSrai64() throws (testing::TestError) { |
| 451 | let enc = encode::srai(super::reg(1), super::reg(2), 32); |
| 452 | try expectEncoding(enc, 0x42015093); |
| 453 | } |
| 454 | |
| 455 | /////////////////////////// |
| 456 | // Pseudo-instruction tests |
| 457 | /////////////////////////// |
| 458 | |
| 459 | @test fn testEncodeNop() throws (testing::TestError) { |
| 460 | let enc = encode::nop(); |
| 461 | try expectEncoding(enc, 0x00000013); |
| 462 | } |
| 463 | |
| 464 | @test fn testEncodeMv() throws (testing::TestError) { |
| 465 | let enc = encode::mv(super::reg(1), super::reg(2)); |
| 466 | try expectEncoding(enc, 0x00010093); |
| 467 | } |
| 468 | |
| 469 | @test fn testEncodeNot() throws (testing::TestError) { |
| 470 | let enc = encode::not_(super::reg(1), super::reg(2)); |
| 471 | try expectEncoding(enc, 0xFFF14093); |
| 472 | } |
| 473 | |
| 474 | @test fn testEncodeNeg() throws (testing::TestError) { |
| 475 | let enc = encode::neg(super::reg(1), super::reg(2)); |
| 476 | try expectEncoding(enc, 0x402000B3); |
| 477 | } |
| 478 | |
| 479 | @test fn testEncodeRet() throws (testing::TestError) { |
| 480 | let enc = encode::ret(); |
| 481 | try expectEncoding(enc, 0x00008067); |
| 482 | } |
| 483 | |
| 484 | @test fn testEncodeJ() throws (testing::TestError) { |
| 485 | let enc = encode::j(8); |
| 486 | try expectEncoding(enc, 0x0080006F); |
| 487 | } |
| 488 | |
| 489 | @test fn testEncodeBle() throws (testing::TestError) { |
| 490 | let enc = encode::ble(super::reg(1), super::reg(2), 8); |
| 491 | try expectEncoding(enc, 0x00115463); |
| 492 | } |
| 493 | |
| 494 | @test fn testEncodeBgt() throws (testing::TestError) { |
| 495 | let enc = encode::bgt(super::reg(1), super::reg(2), 8); |
| 496 | try expectEncoding(enc, 0x00114463); |
| 497 | } |
| 498 | |
| 499 | @test fn testEncodeSeqz() throws (testing::TestError) { |
| 500 | let enc = encode::seqz(super::reg(1), super::reg(2)); |
| 501 | try expectEncoding(enc, 0x00113093); |
| 502 | } |
| 503 | |
| 504 | @test fn testEncodeSnez() throws (testing::TestError) { |
| 505 | let enc = encode::snez(super::reg(1), super::reg(2)); |
| 506 | try expectEncoding(enc, 0x002030B3); |
| 507 | } |
| 508 | |
| 509 | @test fn testEncodeBeqz() throws (testing::TestError) { |
| 510 | let enc = encode::beqz(super::reg(1), 8); |
| 511 | try expectEncoding(enc, 0x00008463); |
| 512 | } |
| 513 | |
| 514 | @test fn testEncodeBnez() throws (testing::TestError) { |
| 515 | let enc = encode::bnez(super::reg(1), 8); |
| 516 | try expectEncoding(enc, 0x00009463); |
| 517 | } |
| 518 | |
| 519 | @test fn testEncodeCall() throws (testing::TestError) { |
| 520 | let enc = encode::call(8); |
| 521 | try expectEncoding(enc, 0x008000EF); |
| 522 | } |
| 523 | |
| 524 | ///////////////////////////// |
| 525 | // Validation helper tests // |
| 526 | ///////////////////////////// |
| 527 | |
| 528 | @test fn testIsSmallImm() throws (testing::TestError) { |
| 529 | try testing::expect(encode::isSmallImm(0)); |
| 530 | try testing::expect(encode::isSmallImm(2047)); |
| 531 | try testing::expect(encode::isSmallImm(-2048)); |
| 532 | try testing::expect(encode::isSmallImm(-1)); |
| 533 | try testing::expectNot(encode::isSmallImm(2048)); |
| 534 | try testing::expectNot(encode::isSmallImm(-2049)); |
| 535 | } |
| 536 | |
| 537 | @test fn testIsBranchImm() throws (testing::TestError) { |
| 538 | try testing::expect(encode::isBranchImm(0)); |
| 539 | try testing::expect(encode::isBranchImm(8)); |
| 540 | try testing::expect(encode::isBranchImm(-8)); |
| 541 | try testing::expect(encode::isBranchImm(4094)); |
| 542 | try testing::expect(encode::isBranchImm(-4096)); |
| 543 | try testing::expectNot(encode::isBranchImm(1)); // Must be even |
| 544 | try testing::expectNot(encode::isBranchImm(4096)); // Out of range |
| 545 | } |
| 546 | |
| 547 | @test fn testIsJumpImm() throws (testing::TestError) { |
| 548 | try testing::expect(encode::isJumpImm(0)); |
| 549 | try testing::expect(encode::isJumpImm(8)); |
| 550 | try testing::expect(encode::isJumpImm(-8)); |
| 551 | try testing::expect(encode::isJumpImm(1048574)); // Max positive even |
| 552 | try testing::expect(encode::isJumpImm(-1048576)); // Min negative |
| 553 | try testing::expectNot(encode::isJumpImm(1)); // Must be even |
| 554 | try testing::expectNot(encode::isJumpImm(1048576)); // Out of range |
| 555 | } |