Module: AArch64::Utils
- Defined in:
- lib/aarch64/utils.rb
Constant Summary collapse
- EncodedMask =
ClassGen.pos(:n, :immr, :imms)
- MAX_INT_64 =
0xFFFFFFFFFFFFFFFF
- COND_TABLE =
{ "EQ" => 0b0000, "NE" => 0b0001, "CS" => 0b0010, "HS" => 0b0010, "CC" => 0b0011, "LO" => 0b0011, "MI" => 0b0100, "PL" => 0b0101, "VS" => 0b0110, "VC" => 0b0111, "HI" => 0b1000, "LS" => 0b1001, "GE" => 0b1010, "LT" => 0b1011, "GT" => 0b1100, "LE" => 0b1101, "AL" => 0b1110, "NVb" => 0b1111, }
- DC_OP =
{ # dc_op op1, CRm, op2 "IVAC" => [0b0000, 0b0110, 0b0001], "ISW" => [0b0000, 0b0110, 0b0010], "IGVAC" => [0b0000, 0b0110, 0b0011], "IGSW" => [0b0000, 0b0110, 0b0100], "IGDVAC" => [0b0000, 0b0110, 0b0101], "IGDSW" => [0b0000, 0b0110, 0b0110], "CSW" => [0b0000, 0b1010, 0b0010], "CGSW" => [0b0000, 0b1010, 0b0100], "CGDSW" => [0b0000, 0b1010, 0b0110], "CISW" => [0b0000, 0b1110, 0b0010], "CIGSW" => [0b0000, 0b1110, 0b0100], "CIGDSW" => [0b0000, 0b1110, 0b0110], "ZVA" => [0b0011, 0b0100, 0b0001], "GVA" => [0b0011, 0b0100, 0b0011], "GZVA" => [0b0011, 0b0100, 0b0100], "CVAC" => [0b0011, 0b1010, 0b0001], "CGVAC" => [0b0011, 0b1010, 0b0011], "CGDVAC" => [0b0011, 0b1010, 0b0101], "CVAU" => [0b0011, 0b1011, 0b0001], "CVAP" => [0b0011, 0b1100, 0b0001], "CGVAP" => [0b0011, 0b1100, 0b0011], "CGDVAP" => [0b0011, 0b1100, 0b0101], "CVADP" => [0b0011, 0b1101, 0b0001], "CGVADP" => [0b0011, 0b1101, 0b0011], "CGDVADP" => [0b0011, 0b1101, 0b0101], "CIVAC" => [0b0011, 0b1110, 0b0001], "CIGVAC" => [0b0011, 0b1110, 0b0011], "CIGDVAC" => [0b0011, 0b1110, 0b0101], }
- DMB_OPTIONS =
{ "oshld" => 0b0001, "oshst" => 0b0010, "osh" => 0b0011, "nshld" => 0b0101, "nshst" => 0b0110, "nsh" => 0b0111, "ishld" => 0b1001, "ishst" => 0b1010, "ish" => 0b1011, "ld" => 0b1101, "st" => 0b1110, "sy" => 0b1111, }
- IC_OPTIONS =
{ # op1, CRm, op2 "ialluis" => [0b000, 0b0001, 0b00], "iallu" => [0b000, 0b0101, 0b00], "ivau" => [0b011, 0b0101, 0b01], }
- TLBI_OPTIONS =
{ # op1, CRm, op2, "VMALLE1OS" => [0b0000, 0b0001, 0b0000], "VAE1OS" => [0b0000, 0b0001, 0b0001], "ASIDE1OS" => [0b0000, 0b0001, 0b0010], "VAAE1OS" => [0b0000, 0b0001, 0b0011], "VALE1OS" => [0b0000, 0b0001, 0b0101], "VAALE1OS" => [0b0000, 0b0001, 0b0111], "RVAE1IS" => [0b0000, 0b0010, 0b0001], "RVAAE1IS" => [0b0000, 0b0010, 0b0011], "RVALE1IS" => [0b0000, 0b0010, 0b0101], "RVAALE1IS" => [0b0000, 0b0010, 0b0111], "VMALLE1IS" => [0b0000, 0b0011, 0b0000], "VAE1IS" => [0b0000, 0b0011, 0b0001], "ASIDE1IS" => [0b0000, 0b0011, 0b0010], "VAAE1IS" => [0b0000, 0b0011, 0b0011], "VALE1IS" => [0b0000, 0b0011, 0b0101], "VAALE1IS" => [0b0000, 0b0011, 0b0111], "RVAE1OS" => [0b0000, 0b0101, 0b0001], "RVAAE1OS" => [0b0000, 0b0101, 0b0011], "RVALE1OS" => [0b0000, 0b0101, 0b0101], "RVAALE1OS" => [0b0000, 0b0101, 0b0111], "RVAE1" => [0b0000, 0b0110, 0b0001], "RVAAE1" => [0b0000, 0b0110, 0b0011], "RVALE1" => [0b0000, 0b0110, 0b0101], "RVAALE1" => [0b0000, 0b0110, 0b0111], "VMALLE1" => [0b0000, 0b0111, 0b0000], "VAE1" => [0b0000, 0b0111, 0b0001], "ASIDE1" => [0b0000, 0b0111, 0b0010], "VAAE1" => [0b0000, 0b0111, 0b0011], "VALE1" => [0b0000, 0b0111, 0b0101], "VAALE1" => [0b0000, 0b0111, 0b0111], "IPAS2E1IS" => [0b0100, 0b0000, 0b0001], "RIPAS2E1IS" => [0b0100, 0b0000, 0b0010], "IPAS2LE1IS" => [0b0100, 0b0000, 0b0101], "RIPAS2LE1IS" => [0b0100, 0b0000, 0b0110], "ALLE2OS" => [0b0100, 0b0001, 0b0000], "VAE2OS" => [0b0100, 0b0001, 0b0001], "ALLE1OS" => [0b0100, 0b0001, 0b0100], "VALE2OS" => [0b0100, 0b0001, 0b0101], "VMALLS12E1OS" => [0b0100, 0b0001, 0b0110], "RVAE2IS" => [0b0100, 0b0010, 0b0001], "RVALE2IS" => [0b0100, 0b0010, 0b0101], "ALLE2IS" => [0b0100, 0b0011, 0b0000], "VAE2IS" => [0b0100, 0b0011, 0b0001], "ALLE1IS" => [0b0100, 0b0011, 0b0100], "VALE2IS" => [0b0100, 0b0011, 0b0101], "VMALLS12E1IS" => [0b0100, 0b0011, 0b0110], "IPAS2E1OS" => [0b0100, 0b0100, 0b0000], "IPAS2E1" => [0b0100, 0b0100, 0b0001], "RIPAS2E1" => [0b0100, 0b0100, 0b0010], "RIPAS2E1OS" => [0b0100, 0b0100, 0b0011], "IPAS2LE1OS" => [0b0100, 0b0100, 0b0100], "IPAS2LE1" => [0b0100, 0b0100, 0b0101], "RIPAS2LE1" => [0b0100, 0b0100, 0b0110], "RIPAS2LE1OS" => [0b0100, 0b0100, 0b0111], "RVAE2OS" => [0b0100, 0b0101, 0b0001], "RVALE2OS" => [0b0100, 0b0101, 0b0101], "RVAE2" => [0b0100, 0b0110, 0b0001], "RVALE2" => [0b0100, 0b0110, 0b0101], "ALLE2" => [0b0100, 0b0111, 0b0000], "VAE2" => [0b0100, 0b0111, 0b0001], "ALLE1" => [0b0100, 0b0111, 0b0100], "VALE2" => [0b0100, 0b0111, 0b0101], "VMALLS12E1" => [0b0100, 0b0111, 0b0110], "ALLE3OS" => [0b0110, 0b0001, 0b0000], "VAE3OS" => [0b0110, 0b0001, 0b0001], "VALE3OS" => [0b0110, 0b0001, 0b0101], "RVAE3IS" => [0b0110, 0b0010, 0b0001], "RVALE3IS" => [0b0110, 0b0010, 0b0101], "ALLE3IS" => [0b0110, 0b0011, 0b0000], "VAE3IS" => [0b0110, 0b0011, 0b0001], "VALE3IS" => [0b0110, 0b0011, 0b0101], "RVAE3OS" => [0b0110, 0b0101, 0b0001], "RVALE3OS" => [0b0110, 0b0101, 0b0101], "RVAE3" => [0b0110, 0b0110, 0b0001], "RVALE3" => [0b0110, 0b0110, 0b0101], "ALLE3" => [0b0110, 0b0111, 0b0000], "VAE3" => [0b0110, 0b0111, 0b0001], "VALE3" => [0b0110, 0b0111, 0b0101], }
- AT_TABLE =
{ :s1e1r => { :op1 => 0b000, :crm => 0b1000, :op2 => 0b000 }, :s1e1w => { :op1 => 0b000, :crm => 0b1000, :op2 => 0b001 }, :s1e0r => { :op1 => 0b000, :crm => 0b1000, :op2 => 0b010 }, :s1e0w => { :op1 => 0b000, :crm => 0b1000, :op2 => 0b011 }, :s1e1rp => { :op1 => 0b000, :crm => 0b1001, :op2 => 0b000 }, :s1e1wp => { :op1 => 0b000, :crm => 0b1001, :op2 => 0b001 }, :s1e2r => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b000 }, :s1e2w => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b001 }, :s12e1r => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b100 }, :s12e1w => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b101 }, :s12e0r => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b110 }, :s12e0w => { :op1 => 0b100, :crm => 0b1000, :op2 => 0b111 }, :s1e3r => { :op1 => 0b110, :crm => 0b1000, :op2 => 0b000 }, :s1e3w => { :op1 => 0b110, :crm => 0b1000, :op2 => 0b001 }, }
Class Method Summary collapse
- .at_op(at_op) ⇒ Object
- .cond2bin(cond) ⇒ Object
- .count_leading_ones(num) ⇒ Object
- .count_trailing_ones(num) ⇒ Object
- .count_trailing_zeros(num) ⇒ Object
- .dc_op(v) ⇒ Object
- .dmb2imm(option) ⇒ Object
- .encode_mask(imm, regsize) ⇒ Object
- .ic_op(name) ⇒ Object
- .mask?(num) ⇒ Boolean
- .prfop(sym) ⇒ Object
- .shifted_mask?(num) ⇒ Boolean
- .sub_decode_extend32(extend) ⇒ Object
- .sub_decode_extend64(extend) ⇒ Object
- .tlbi_op(name) ⇒ Object
Class Method Details
.at_op(at_op) ⇒ Object
331 332 333 |
# File 'lib/aarch64/utils.rb', line 331 def at_op at_op AT_TABLE.fetch at_op end |
.cond2bin(cond) ⇒ Object
41 42 43 |
# File 'lib/aarch64/utils.rb', line 41 def cond2bin cond COND_TABLE.fetch(cond.to_s.upcase) end |
.count_leading_ones(num) ⇒ Object
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/aarch64/utils.rb', line 80 def count_leading_ones num count = 0 top_bit = 1 << 63 loop do break if num & top_bit != top_bit count += 1 (num <<= 1) & MAX_INT_64 end count end |
.count_trailing_ones(num) ⇒ Object
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/aarch64/utils.rb', line 68 def count_trailing_ones num count = 0 loop do break if num & 1 == 0 count += 1 num >>= 1 end count end |
.count_trailing_zeros(num) ⇒ Object
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/aarch64/utils.rb', line 56 def count_trailing_zeros num count = 0 loop do break if num & 1 == 1 count += 1 num >>= 1 end count end |
.dc_op(v) ⇒ Object
162 163 164 |
# File 'lib/aarch64/utils.rb', line 162 def dc_op v DC_OP.fetch(v.to_s.upcase) end |
.dmb2imm(option) ⇒ Object
182 183 184 |
# File 'lib/aarch64/utils.rb', line 182 def dmb2imm option DMB_OPTIONS.fetch(option.to_s.downcase) end |
.encode_mask(imm, regsize) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/aarch64/utils.rb', line 92 def encode_mask imm, regsize size = regsize loop do size >>= 1 mask = (1 << size) - 1 if (imm & mask) != ((imm >> size) & mask) size <<= 1 break end break unless size > 2 end mask = (-1 & MAX_INT_64) >> (64 - size) imm &= mask if shifted_mask?(imm) i = count_trailing_zeros imm cto = count_trailing_ones(imm >> i) else imm |= ((~mask) & MAX_INT_64) unless shifted_mask?((~imm) & MAX_INT_64) return nil end clo = count_leading_ones(imm & MAX_INT_64) i = 64 - clo cto = clo + count_trailing_ones(imm) - (64 - size) end immr = (size - i) & (size - 1) imms = (~(size - 1) << 1) | (cto - 1) n = ((imms >> 6) & 1) ^ 1 EncodedMask.new(n, immr & 0x3F, imms & 0x3F) end |
.ic_op(name) ⇒ Object
194 195 196 |
# File 'lib/aarch64/utils.rb', line 194 def ic_op name IC_OPTIONS.fetch(name.to_s.downcase) end |
.mask?(num) ⇒ Boolean
46 47 48 |
# File 'lib/aarch64/utils.rb', line 46 def mask? num ((num + 1) & num) == 0 end |
.prfop(sym) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/aarch64/utils.rb', line 285 def prfop sym if sym.to_s =~ /^(\w{3})(\w\w)(\w{4})$/ x = case $1 when "pld" then (0b00 << 3) when "pli" then (0b01 << 3) when "pst" then (0b10 << 3) else raise "unknown key #{$1}" end y = case $2 when "l1" then (0b00 << 1) when "l2" then (0b01 << 1) when "l3" then (0b10 << 1) else raise "unknown key #{$2}" end z = case $3 when "keep" then 0b0 when "strm" then 0b1 else raise "unknown key #{$3}" end x | y | z else raise ArgumentError, sym.to_s end end |
.shifted_mask?(num) ⇒ Boolean
51 52 53 |
# File 'lib/aarch64/utils.rb', line 51 def shifted_mask? num mask?((num - 1) | num) end |
.sub_decode_extend32(extend) ⇒ Object
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/aarch64/utils.rb', line 336 def sub_decode_extend32 extend case extend when :uxtb then 0b000 when :uxth then 0b001 when :uxtw then 0b010 when :lsl then 0b010 when :uxtx then 0b011 when :sxtb then 0b100 when :sxth then 0b101 when :sxtw then 0b110 when :sxtx then 0b111 else raise "Unknown extend #{extend}" end end |
.sub_decode_extend64(extend) ⇒ Object
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/aarch64/utils.rb', line 353 def sub_decode_extend64 extend case extend when :uxtb then 0b000 when :uxth then 0b001 when :uxtw then 0b011 when :lsl then 0b011 when :uxtx then 0b011 when :sxtb then 0b100 when :sxth then 0b101 when :sxtw then 0b110 when :sxtx then 0b111 else raise "Unknown extend #{extend}" end end |
.tlbi_op(name) ⇒ Object
280 281 282 |
# File 'lib/aarch64/utils.rb', line 280 def tlbi_op name TLBI_OPTIONS.fetch(name.to_s.upcase) end |