| ... | ... | @@ -513,14 +513,16 @@ pub const Instruction = union(enum) { |
| 513 | 513 | } |
| 514 | 514 | |
| 515 | 515 | fn format1(disp: i32) Instruction { |
| 516 | const udisp = @bitCast(u32, disp); |
| 517 | |
| 516 | 518 | // In SPARC, branch target needs to be aligned to 4 bytes. |
| 517 | | assert(disp % 4 == 0); |
| 519 | assert(udisp % 4 == 0); |
| 518 | 520 | |
| 519 | 521 | // Discard the last two bits since those are implicitly zero. |
| 520 | | const udisp = @truncate(u30, @bitCast(u32, disp) >> 2); |
| 522 | const udisp_truncated = @truncate(u30, udisp >> 2); |
| 521 | 523 | return Instruction{ |
| 522 | 524 | .format_1 = .{ |
| 523 | | .disp30 = udisp, |
| 525 | .disp30 = udisp_truncated, |
| 524 | 526 | }, |
| 525 | 527 | }; |
| 526 | 528 | } |
| ... | ... | @@ -536,27 +538,31 @@ pub const Instruction = union(enum) { |
| 536 | 538 | } |
| 537 | 539 | |
| 538 | 540 | fn format2b(op2: u3, cond: Condition, annul: bool, disp: i24) Instruction { |
| 541 | const udisp = @bitCast(u24, disp); |
| 542 | |
| 539 | 543 | // In SPARC, branch target needs to be aligned to 4 bytes. |
| 540 | | assert(disp % 4 == 0); |
| 544 | assert(udisp % 4 == 0); |
| 541 | 545 | |
| 542 | 546 | // Discard the last two bits since those are implicitly zero. |
| 543 | | const udisp = @truncate(u22, @bitCast(u24, disp) >> 2); |
| 547 | const udisp_truncated = @truncate(u22, udisp >> 2); |
| 544 | 548 | return Instruction{ |
| 545 | 549 | .format_2b = .{ |
| 546 | 550 | .a = @boolToInt(annul), |
| 547 | 551 | .cond = cond, |
| 548 | 552 | .op2 = op2, |
| 549 | | .disp22 = udisp, |
| 553 | .disp22 = udisp_truncated, |
| 550 | 554 | }, |
| 551 | 555 | }; |
| 552 | 556 | } |
| 553 | 557 | |
| 554 | 558 | fn format2c(op2: u3, cond: Condition, annul: bool, pt: bool, ccr: CCR, disp: i21) Instruction { |
| 559 | const udisp = @bitCast(u21, disp); |
| 560 | |
| 555 | 561 | // In SPARC, branch target needs to be aligned to 4 bytes. |
| 556 | | assert(disp % 4 == 0); |
| 562 | assert(udisp % 4 == 0); |
| 557 | 563 | |
| 558 | 564 | // Discard the last two bits since those are implicitly zero. |
| 559 | | const udisp = @truncate(u19, @bitCast(u21, disp) >> 2); |
| 565 | const udisp_truncated = @truncate(u19, udisp >> 2); |
| 560 | 566 | |
| 561 | 567 | const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1); |
| 562 | 568 | const ccr_cc0 = @truncate(u1, @enumToInt(ccr)); |
| ... | ... | @@ -568,18 +574,19 @@ pub const Instruction = union(enum) { |
| 568 | 574 | .cc1 = ccr_cc1, |
| 569 | 575 | .cc0 = ccr_cc0, |
| 570 | 576 | .p = @boolToInt(pt), |
| 571 | | .disp19 = udisp, |
| 577 | .disp19 = udisp_truncated, |
| 572 | 578 | }, |
| 573 | 579 | }; |
| 574 | 580 | } |
| 575 | 581 | |
| 576 | 582 | fn format2d(op2: u3, rcond: RCondition, annul: bool, pt: bool, rs1: Register, disp: i18) Instruction { |
| 583 | const udisp = @truncate(u16, @bitCast(u18, disp) >> 2); |
| 584 | |
| 577 | 585 | // In SPARC, branch target needs to be aligned to 4 bytes. |
| 578 | | assert(disp % 4 == 0); |
| 586 | assert(udisp % 4 == 0); |
| 579 | 587 | |
| 580 | 588 | // Discard the last two bits since those are implicitly zero, |
| 581 | 589 | // and split it into low and high parts. |
| 582 | | const udisp = @truncate(u16, @bitCast(u18, disp) >> 2); |
| 583 | 590 | const udisp_hi = @truncate(u2, (udisp & 0b1100_0000_0000_0000) >> 14); |
| 584 | 591 | const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111); |
| 585 | 592 | return Instruction{ |