1 module zua.vm.std.bit32; 2 import zua.vm.engine; 3 import zua.vm.reflection; 4 import std.typecons; 5 6 private uint lbit32_arshift(uint x, long disp) { 7 if (disp < 0) return x << -disp; 8 return cast(uint)(cast(int)x >> disp); 9 } 10 11 private uint lbit32_band(uint[] op...) { 12 uint res = 0xFFFFFFFF; 13 foreach (i; op) { 14 res &= i; 15 } 16 return res; 17 } 18 19 private uint lbit32_bnot(uint x) { 20 return ~x; 21 } 22 23 private uint lbit32_bor(uint[] op...) { 24 uint res = 0; 25 foreach (i; op) { 26 res |= i; 27 } 28 return res; 29 } 30 31 private bool lbit32_btest(uint[] op...) { 32 uint res = 0xFFFFFFFF; 33 foreach (i; op) { 34 res &= i; 35 } 36 return res != 0; 37 } 38 39 private uint lbit32_bxor(uint[] op...) { 40 uint res = 0; 41 foreach (i; op) { 42 res ^= i; 43 } 44 return res; 45 } 46 47 private uint lbit32_extract(uint x, long start, long width = 1) { 48 if (start < 0) { 49 throw new Exception("bad argument #2 to 'extract' (field cannot be negative)"); 50 } 51 else if (width < 1) { 52 throw new Exception("bad argument #3 to 'extract' (width must be positive)"); 53 } 54 else if (start + width > 32) { 55 throw new Exception("trying to access non-existent bits"); 56 } 57 else if (width == 32) { 58 return x; 59 } 60 61 return (x >> start) & (1 << width) - 1; 62 } 63 64 private uint lbit32_replace(uint x, uint v, long start, long width = 1) { 65 if (start < 0) { 66 throw new Exception("bad argument #2 to 'replace' (field cannot be negative)"); 67 } 68 else if (width < 1) { 69 throw new Exception("bad argument #3 to 'replace' (width must be positive)"); 70 } 71 else if (start + width > 32) { 72 throw new Exception("trying to access non-existent bits"); 73 } 74 else if (width == 32) { 75 return v; 76 } 77 78 uint zeroed = x & ~((1 << width) - 1 << start); 79 return zeroed | ((v & (1 << width) - 1) << start); 80 } 81 82 private uint lbit32_lrotate(uint x, long disp) { 83 disp %= 32; 84 if (disp < 0) disp += 32; 85 return (x << disp) | (x >> (32 - disp)); 86 } 87 88 private uint lbit32_lshift(uint x, long disp) { 89 if (disp >= 32 || disp <= -32) return 0; 90 if (disp < 0) return x >> -disp; 91 return x << disp; 92 } 93 94 private uint lbit32_rrotate(uint x, long disp) { 95 disp %= 32; 96 if (disp < 0) disp += 32; 97 return (x >> disp) | (x << (32 - disp)); 98 } 99 100 private uint lbit32_rshift(uint x, long disp) { 101 if (disp >= 32 || disp <= -32) return 0; 102 if (disp < 0) return x << -disp; 103 return x >> disp; 104 } 105 106 /** Get bit32 library */ 107 Value bit32lib() { 108 TableValue res = new TableValue; 109 res.set(Value("arshift"), exposeFunction!(lbit32_arshift, "arshift")); 110 res.set(Value("band"), exposeFunction!(lbit32_band, "band")); 111 res.set(Value("bnot"), exposeFunction!(lbit32_bnot, "bnot")); 112 res.set(Value("bor"), exposeFunction!(lbit32_bor, "bor")); 113 res.set(Value("btest"), exposeFunction!(lbit32_btest, "btest")); 114 res.set(Value("bxor"), exposeFunction!(lbit32_bxor, "bxor")); 115 res.set(Value("extract"), exposeFunction!(lbit32_extract, "extract")); 116 res.set(Value("replace"), exposeFunction!(lbit32_replace, "replace")); 117 res.set(Value("lrotate"), exposeFunction!(lbit32_lrotate, "lrotate")); 118 res.set(Value("lshift"), exposeFunction!(lbit32_lshift, "lshift")); 119 res.set(Value("rrotate"), exposeFunction!(lbit32_rrotate, "rrotate")); 120 res.set(Value("rshift"), exposeFunction!(lbit32_rshift, "rshift")); 121 return Value(res); 122 }