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