152a153,155
> 0x1: mul({{
> Rd = Rs1_sd*Rs2_sd;
> }}, IntMultOp);
160a164,181
> 0x1: mulh({{
> bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
>
> uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
> uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
> uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
> uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32;
>
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs2_lo*Rs1_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
> Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res;
> }}, IntMultOp);
165a187,203
> 0x1: mulhsu({{
> bool negate = Rs1_sd < 0;
> uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
> uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
> uint64_t Rs2_lo = (uint32_t)Rs2;
> uint64_t Rs2_hi = Rs2 >> 32;
>
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs1_lo*Rs2_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
> Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
> }}, IntMultOp);
170a209,223
> 0x1: mulhu({{
> uint64_t Rs1_lo = (uint32_t)Rs1;
> uint64_t Rs1_hi = Rs1 >> 32;
> uint64_t Rs2_lo = (uint32_t)Rs2;
> uint64_t Rs2_hi = Rs2 >> 32;
>
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs1_lo*Rs2_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
> }}, IntMultOp);
175a229,238
> 0x1: div({{
> if (Rs2_sd == 0) {
> Rd_sd = -1;
> } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
> && Rs2_sd == -1) {
> Rd_sd = std::numeric_limits<int64_t>::min();
> } else {
> Rd_sd = Rs1_sd/Rs2_sd;
> }
> }}, IntDivOp);
180a244,250
> 0x1: divu({{
> if (Rs2 == 0) {
> Rd = std::numeric_limits<uint64_t>::max();
> } else {
> Rd = Rs1/Rs2;
> }
> }}, IntDivOp);
188a259,268
> 0x1: rem({{
> if (Rs2_sd == 0) {
> Rd = Rs1_sd;
> } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
> && Rs2_sd == -1) {
> Rd = 0;
> } else {
> Rd = Rs1_sd%Rs2_sd;
> }
> }}, IntDivOp);
193a274,280
> 0x1: remu({{
> if (Rs2 == 0) {
> Rd = Rs1;
> } else {
> Rd = Rs1%Rs2;
> }
> }}, IntDivOp);
207a295,297
> 0x1: mulw({{
> Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
> }}, IntMultOp);
214a305,314
> 0x4: divw({{
> if (Rs2_sw == 0) {
> Rd_sd = -1;
> } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
> && Rs2_sw == -1) {
> Rd_sd = std::numeric_limits<int32_t>::min();
> } else {
> Rd_sd = Rs1_sw/Rs2_sw;
> }
> }}, IntDivOp);
218a319,325
> 0x1: divuw({{
> if (Rs2_uw == 0) {
> Rd_sd = std::numeric_limits<IntReg>::max();
> } else {
> Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
> }
> }}, IntDivOp);
222a330,346
> 0x6: remw({{
> if (Rs2_sw == 0) {
> Rd_sd = Rs1_sw;
> } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
> && Rs2_sw == -1) {
> Rd_sd = 0;
> } else {
> Rd_sd = Rs1_sw%Rs2_sw;
> }
> }}, IntDivOp);
> 0x7: remuw({{
> if (Rs2_uw == 0) {
> Rd_sd = (int32_t)Rs1_uw;
> } else {
> Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
> }
> }}, IntDivOp);