diff --git a/include/oaknut/impl/arm64_encode_helpers.inc.hpp b/include/oaknut/impl/arm64_encode_helpers.inc.hpp index 7bbdc8d..2675a3f 100644 --- a/include/oaknut/impl/arm64_encode_helpers.inc.hpp +++ b/include/oaknut/impl/arm64_encode_helpers.inc.hpp @@ -8,7 +8,7 @@ static constexpr std::uint32_t pdep(std::uint32_t val) std::uint32_t res = 0; for (std::uint32_t bb = 1; mask; bb += bb) { if (val & bb) - res |= mask & -mask; + res |= mask & (~mask + 1); mask &= mask - 1; } return res; diff --git a/include/oaknut/impl/mnemonics_generic_v8.0.inc.hpp b/include/oaknut/impl/mnemonics_generic_v8.0.inc.hpp index 4f5ca8f..09e8665 100644 --- a/include/oaknut/impl/mnemonics_generic_v8.0.inc.hpp +++ b/include/oaknut/impl/mnemonics_generic_v8.0.inc.hpp @@ -167,13 +167,13 @@ void BFI(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width) { if (width.value() == 0 || width.value() > (32 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"0011001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1); + emit<"0011001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (~lsb.value() + 1) & 31, width.value() - 1); } void BFI(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width) { if (width.value() == 0 || width.value() > (64 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"1011001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1); + emit<"1011001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (~lsb.value() + 1) & 63, width.value() - 1); } void BFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms) { @@ -1231,13 +1231,13 @@ void SBFIZ(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width) { if (width.value() == 0 || width.value() > (32 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"0001001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1); + emit<"0001001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (~lsb.value() + 1) & 31, width.value() - 1); } void SBFIZ(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width) { if (width.value() == 0 || width.value() > (64 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"1001001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1); + emit<"1001001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (~lsb.value() + 1) & 63, width.value() - 1); } void SBFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms) { @@ -1627,13 +1627,13 @@ void UBFIZ(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width) { if (width.value() == 0 || width.value() > (32 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"0101001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1); + emit<"0101001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (~lsb.value() + 1) & 31, width.value() - 1); } void UBFIZ(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width) { if (width.value() == 0 || width.value() > (64 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"1101001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1); + emit<"1101001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (~lsb.value() + 1) & 63, width.value() - 1); } void UBFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms) { diff --git a/include/oaknut/impl/mnemonics_generic_v8.2.inc.hpp b/include/oaknut/impl/mnemonics_generic_v8.2.inc.hpp index a5bc5b8..0dffd0e 100644 --- a/include/oaknut/impl/mnemonics_generic_v8.2.inc.hpp +++ b/include/oaknut/impl/mnemonics_generic_v8.2.inc.hpp @@ -5,13 +5,13 @@ void BFC(WReg wd, Imm<5> lsb, Imm<5> width) { if (width.value() == 0 || width.value() > (32 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"0011001100rrrrrrssssss11111ddddd", "d", "r", "s">(wd, (-lsb.value()) & 31, width.value() - 1); + emit<"0011001100rrrrrrssssss11111ddddd", "d", "r", "s">(wd, (~lsb.value() + 1) & 31, width.value() - 1); } void BFC(XReg xd, Imm<6> lsb, Imm<6> width) { if (width.value() == 0 || width.value() > (64 - lsb.value())) throw OaknutException{ExceptionType::InvalidBitWidth}; - emit<"1011001101rrrrrrssssss11111ddddd", "d", "r", "s">(xd, (-lsb.value()) & 63, width.value() - 1); + emit<"1011001101rrrrrrssssss11111ddddd", "d", "r", "s">(xd, (~lsb.value() + 1) & 63, width.value() - 1); } void ESB() { diff --git a/include/oaknut/oaknut.hpp b/include/oaknut/oaknut.hpp index a091ff5..fc0ffcc 100644 --- a/include/oaknut/oaknut.hpp +++ b/include/oaknut/oaknut.hpp @@ -110,8 +110,8 @@ public: return; if (MovImm16::is_valid(imm)) return MOVZ(wd, imm); - if (MovImm16::is_valid(~static_cast(imm))) - return MOVN(wd, ~static_cast(imm)); + if (MovImm16::is_valid(static_cast(~imm))) + return MOVN(wd, static_cast(~imm)); if (detail::encode_bit_imm(imm)) return ORR(wd, WzrReg{}, imm);