ling_iops.erl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. %% Copyright (c) 2013-2014 Cloudozer LLP. All rights reserved.
  2. %%
  3. %% Redistribution and use in source and binary forms, with or without
  4. %% modification, are permitted provided that the following conditions are met:
  5. %%
  6. %% * Redistributions of source code must retain the above copyright notice, this
  7. %% list of conditions and the following disclaimer.
  8. %%
  9. %% * Redistributions in binary form must reproduce the above copyright notice,
  10. %% this list of conditions and the following disclaimer in the documentation
  11. %% and/or other materials provided with the distribution.
  12. %%
  13. %% * Redistributions in any form must be accompanied by information on how to
  14. %% obtain complete source code for the LING software and any accompanying
  15. %% software that uses the LING software. The source code must either be included
  16. %% in the distribution or be available for no more than the cost of distribution
  17. %% plus a nominal fee, and must be freely redistributable under reasonable
  18. %% conditions. For an executable file, complete source code means the source
  19. %% code for all modules it contains. It does not include source code for modules
  20. %% or files that typically accompany the major components of the operating
  21. %% system on which the executable file runs.
  22. %%
  23. %% THIS SOFTWARE IS PROVIDED BY CLOUDOZER LLP ``AS IS'' AND ANY EXPRESS OR
  24. %% IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25. %% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE
  26. %% DISCLAIMED. IN NO EVENT SHALL CLOUDOZER LLP BE LIABLE FOR ANY DIRECT,
  27. %% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. %% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. %% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  30. %% ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. %% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. -module(ling_iops).
  34. -export([packing_options/1,broadest_packing/1]).
  35. -export([packing_tags/1,wsize/1]).
  36. broadest_packing(Types) ->
  37. [broad(T) || T <- Types].
  38. broad(u) -> u32;
  39. broad(u8) -> u8;
  40. broad(a) -> t;
  41. broad(x) -> t;
  42. broad(y) -> t;
  43. broad(d) -> t;
  44. broad(s) -> t;
  45. broad(f) -> f;
  46. broad(e) -> e;
  47. broad(fu) -> fu;
  48. broad(str) -> str;
  49. broad(ca) -> t;
  50. broad(b) -> b;
  51. broad(fr) -> fr.
  52. packing_options(Args) ->
  53. generate(fun arg_rep/1, Args).
  54. generate(_, []) ->
  55. [[]];
  56. generate(F, [A|As]) ->
  57. [[G|Gs] || G <- F(A), Gs <- generate(F, As)].
  58. %% NB: the broadest case should be in the end
  59. arg_rep({u8,N}) when is_integer(N), N >= 0, N =< 255 -> [u8];
  60. arg_rep(N) when is_integer(N), N >= 0, N =< 255 -> [u8,u32];
  61. arg_rep(N) when is_integer(N), N >= 0 -> [u32];
  62. arg_rep({a,_}) -> [t];
  63. arg_rep({smallint,I}) when I >= -128, I =< 127 -> [i8,t];
  64. arg_rep({smallint,_I}) -> [t];
  65. arg_rep({bigint,_I}) -> [t];
  66. arg_rep(nil) -> [t];
  67. arg_rep({x,X}) when X =< 255 -> [x8,t];
  68. arg_rep({x,_X}) -> [t];
  69. arg_rep({y,Y}) when Y =< 255 -> [y8,t];
  70. arg_rep({y,_Y}) -> [t];
  71. arg_rep({f,_}) -> [f];
  72. arg_rep({float,_}) -> [t];
  73. arg_rep({fr,_}) -> [fr];
  74. arg_rep({literal,_}) -> [t];
  75. arg_rep({e,_}) -> [e];
  76. arg_rep({bif,_}) -> [b].
  77. bs(u8) -> 8;
  78. bs(u32) -> 32;
  79. bs(i8) -> 8;
  80. bs(x8) -> 8;
  81. bs(y8) -> 8;
  82. bs(t) -> 32;
  83. bs(f) -> 32;
  84. bs(e) -> 32;
  85. bs(b) -> 32;
  86. bs(fr) -> 8;
  87. bs(fu) -> 32;
  88. bs(str) -> 32;
  89. bs(nil) -> 0;
  90. bs({_,_}) -> 0.
  91. wsize(RRR) ->
  92. (lists:sum([bs(A) || A <- RRR]) + 31) div 32.
  93. packing_tags(Ts) ->
  94. packing_tags(Ts, 0, 0, 0, []).
  95. packing_tags([], NW, _, _, Acc) ->
  96. lists:map(fun({T,{bits,NB,Off}}) ->
  97. {T,{bits,NB+NW,Off}};
  98. (X) ->
  99. X
  100. end, lists:reverse(Acc));
  101. packing_tags([{T,V}|Ts], NW, NB, Off, Acc) ->
  102. packing_tags(Ts, NW, NB, Off, [{T,{value,V}}|Acc]);
  103. packing_tags([nil|Ts], NW, NB, Off, Acc) ->
  104. packing_tags(Ts, NW, NB, Off, [{t,{value,nil}}|Acc]);
  105. packing_tags([T|Ts], NW, NB, Off, Acc) ->
  106. case bs(T) of
  107. 8 ->
  108. pack8(T, Ts, NW, NB, Off, Acc);
  109. 32 ->
  110. packing_tags(Ts, NW+1, NB, Off, [{T,{word,NW}}|Acc])
  111. end.
  112. pack8(T, Ts, NW, NB, 0=Off, Acc) ->
  113. packing_tags(Ts, NW, NB+1, 8, [{T,{bits,NB,Off}}|Acc]);
  114. pack8(T, Ts, NW, NB, 24=Off, Acc) ->
  115. packing_tags(Ts, NW, NB, 0, [{T,{bits,NB-1,Off}}|Acc]);
  116. pack8(T, Ts, NW, NB, Off, Acc) ->
  117. packing_tags(Ts, NW, NB, Off+8, [{T,{bits,NB-1,Off}}|Acc]).
  118. %%EOF