Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2003 VMware, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  9.  * license, and/or sell copies of the Software, and to permit persons to whom
  10.  * the Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
  19.  * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Keith Whitwell <keithw@vmware.com>
  26.  */
  27.  
  28.  
  29. #include "pipe/p_config.h"
  30. #include "pipe/p_compiler.h"
  31. #include "util/u_memory.h"
  32. #include "util/u_math.h"
  33. #include "util/u_format.h"
  34.  
  35. #include "translate.h"
  36.  
  37.  
  38. #if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && !defined(PIPE_SUBSYSTEM_EMBEDDED)
  39.  
  40. #include "rtasm/rtasm_cpu.h"
  41. #include "rtasm/rtasm_x86sse.h"
  42.  
  43.  
  44. #define X    0
  45. #define Y    1
  46. #define Z    2
  47. #define W    3
  48.  
  49.  
  50. struct translate_buffer
  51. {
  52.    const void *base_ptr;
  53.    uintptr_t stride;
  54.    unsigned max_index;
  55. };
  56.  
  57. struct translate_buffer_variant
  58. {
  59.    unsigned buffer_index;
  60.    unsigned instance_divisor;
  61.    void *ptr;                   /* updated either per vertex or per instance */
  62. };
  63.  
  64.  
  65. #define ELEMENT_BUFFER_INSTANCE_ID  1001
  66.  
  67. #define NUM_CONSTS 7
  68.  
  69. enum
  70. {
  71.    CONST_IDENTITY,
  72.    CONST_INV_127,
  73.    CONST_INV_255,
  74.    CONST_INV_32767,
  75.    CONST_INV_65535,
  76.    CONST_INV_2147483647,
  77.    CONST_255
  78. };
  79.  
  80. #define C(v) {(float)(v), (float)(v), (float)(v), (float)(v)}
  81. static float consts[NUM_CONSTS][4] = {
  82.    {0, 0, 0, 1},
  83.    C(1.0 / 127.0),
  84.    C(1.0 / 255.0),
  85.    C(1.0 / 32767.0),
  86.    C(1.0 / 65535.0),
  87.    C(1.0 / 2147483647.0),
  88.    C(255.0)
  89. };
  90.  
  91. #undef C
  92.  
  93. struct translate_sse
  94. {
  95.    struct translate translate;
  96.  
  97.    struct x86_function linear_func;
  98.    struct x86_function elt_func;
  99.    struct x86_function elt16_func;
  100.    struct x86_function elt8_func;
  101.    struct x86_function *func;
  102.  
  103.      PIPE_ALIGN_VAR(16) float consts[NUM_CONSTS][4];
  104.    int8_t reg_to_const[16];
  105.    int8_t const_to_reg[NUM_CONSTS];
  106.  
  107.    struct translate_buffer buffer[TRANSLATE_MAX_ATTRIBS];
  108.    unsigned nr_buffers;
  109.  
  110.    /* Multiple buffer variants can map to a single buffer. */
  111.    struct translate_buffer_variant buffer_variant[TRANSLATE_MAX_ATTRIBS];
  112.    unsigned nr_buffer_variants;
  113.  
  114.    /* Multiple elements can map to a single buffer variant. */
  115.    unsigned element_to_buffer_variant[TRANSLATE_MAX_ATTRIBS];
  116.  
  117.    boolean use_instancing;
  118.    unsigned instance_id;
  119.    unsigned start_instance;
  120.  
  121.    /* these are actually known values, but putting them in a struct
  122.     * like this is helpful to keep them in sync across the file.
  123.     */
  124.    struct x86_reg tmp_EAX;
  125.    struct x86_reg tmp2_EDX;
  126.    struct x86_reg src_ECX;
  127.    struct x86_reg idx_ESI;      /* either start+i or &elt[i] */
  128.    struct x86_reg machine_EDI;
  129.    struct x86_reg outbuf_EBX;
  130.    struct x86_reg count_EBP;    /* decrements to zero */
  131. };
  132.  
  133.  
  134. static int
  135. get_offset(const void *a, const void *b)
  136. {
  137.    return (const char *) b - (const char *) a;
  138. }
  139.  
  140.  
  141. static struct x86_reg
  142. get_const(struct translate_sse *p, unsigned id)
  143. {
  144.    struct x86_reg reg;
  145.    unsigned i;
  146.  
  147.    if (p->const_to_reg[id] >= 0)
  148.       return x86_make_reg(file_XMM, p->const_to_reg[id]);
  149.  
  150.    for (i = 2; i < 8; ++i) {
  151.       if (p->reg_to_const[i] < 0)
  152.          break;
  153.    }
  154.  
  155.    /* TODO: be smarter here */
  156.    if (i == 8)
  157.       --i;
  158.  
  159.    reg = x86_make_reg(file_XMM, i);
  160.  
  161.    if (p->reg_to_const[i] >= 0)
  162.       p->const_to_reg[p->reg_to_const[i]] = -1;
  163.  
  164.    p->reg_to_const[i] = id;
  165.    p->const_to_reg[id] = i;
  166.  
  167.    /* TODO: this should happen outside the loop, if possible */
  168.    sse_movaps(p->func, reg,
  169.               x86_make_disp(p->machine_EDI,
  170.                             get_offset(p, &p->consts[id][0])));
  171.  
  172.    return reg;
  173. }
  174.  
  175.  
  176. /* load the data in a SSE2 register, padding with zeros */
  177. static boolean
  178. emit_load_sse2(struct translate_sse *p,
  179.                struct x86_reg data, struct x86_reg src, unsigned size)
  180. {
  181.    struct x86_reg tmpXMM = x86_make_reg(file_XMM, 1);
  182.    struct x86_reg tmp = p->tmp_EAX;
  183.    switch (size) {
  184.    case 1:
  185.       x86_movzx8(p->func, tmp, src);
  186.       sse2_movd(p->func, data, tmp);
  187.       break;
  188.    case 2:
  189.       x86_movzx16(p->func, tmp, src);
  190.       sse2_movd(p->func, data, tmp);
  191.       break;
  192.    case 3:
  193.       x86_movzx8(p->func, tmp, x86_make_disp(src, 2));
  194.       x86_shl_imm(p->func, tmp, 16);
  195.       x86_mov16(p->func, tmp, src);
  196.       sse2_movd(p->func, data, tmp);
  197.       break;
  198.    case 4:
  199.       sse2_movd(p->func, data, src);
  200.       break;
  201.    case 6:
  202.       sse2_movd(p->func, data, src);
  203.       x86_movzx16(p->func, tmp, x86_make_disp(src, 4));
  204.       sse2_movd(p->func, tmpXMM, tmp);
  205.       sse2_punpckldq(p->func, data, tmpXMM);
  206.       break;
  207.    case 8:
  208.       sse2_movq(p->func, data, src);
  209.       break;
  210.    case 12:
  211.       sse2_movq(p->func, data, src);
  212.       sse2_movd(p->func, tmpXMM, x86_make_disp(src, 8));
  213.       sse2_punpcklqdq(p->func, data, tmpXMM);
  214.       break;
  215.    case 16:
  216.       sse2_movdqu(p->func, data, src);
  217.       break;
  218.    default:
  219.       return FALSE;
  220.    }
  221.    return TRUE;
  222. }
  223.  
  224.  
  225. /* this value can be passed for the out_chans argument */
  226. #define CHANNELS_0001 5
  227.  
  228.  
  229. /* this function will load #chans float values, and will
  230.  * pad the register with zeroes at least up to out_chans.
  231.  *
  232.  * If out_chans is set to CHANNELS_0001, then the fourth
  233.  * value will be padded with 1. Only pass this value if
  234.  * chans < 4 or results are undefined.
  235.  */
  236. static void
  237. emit_load_float32(struct translate_sse *p, struct x86_reg data,
  238.                   struct x86_reg arg0, unsigned out_chans, unsigned chans)
  239. {
  240.    switch (chans) {
  241.    case 1:
  242.       /* a 0 0 0
  243.        * a 0 0 1
  244.        */
  245.       sse_movss(p->func, data, arg0);
  246.       if (out_chans == CHANNELS_0001)
  247.          sse_orps(p->func, data, get_const(p, CONST_IDENTITY));
  248.       break;
  249.    case 2:
  250.       /* 0 0 0 1
  251.        * a b 0 1
  252.        */
  253.       if (out_chans == CHANNELS_0001)
  254.          sse_shufps(p->func, data, get_const(p, CONST_IDENTITY),
  255.                     SHUF(X, Y, Z, W));
  256.       else if (out_chans > 2)
  257.          sse_movlhps(p->func, data, get_const(p, CONST_IDENTITY));
  258.       sse_movlps(p->func, data, arg0);
  259.       break;
  260.    case 3:
  261.       /* Have to jump through some hoops:
  262.        *
  263.        * c 0 0 0
  264.        * c 0 0 1 if out_chans == CHANNELS_0001
  265.        * 0 0 c 0/1
  266.        * a b c 0/1
  267.        */
  268.       sse_movss(p->func, data, x86_make_disp(arg0, 8));
  269.       if (out_chans == CHANNELS_0001)
  270.          sse_shufps(p->func, data, get_const(p, CONST_IDENTITY),
  271.                     SHUF(X, Y, Z, W));
  272.       sse_shufps(p->func, data, data, SHUF(Y, Z, X, W));
  273.       sse_movlps(p->func, data, arg0);
  274.       break;
  275.    case 4:
  276.       sse_movups(p->func, data, arg0);
  277.       break;
  278.    }
  279. }
  280.  
  281. /* this function behaves like emit_load_float32, but loads
  282.    64-bit floating point numbers, converting them to 32-bit
  283.   ones */
  284. static void
  285. emit_load_float64to32(struct translate_sse *p, struct x86_reg data,
  286.                       struct x86_reg arg0, unsigned out_chans, unsigned chans)
  287. {
  288.    struct x86_reg tmpXMM = x86_make_reg(file_XMM, 1);
  289.    switch (chans) {
  290.    case 1:
  291.       sse2_movsd(p->func, data, arg0);
  292.       if (out_chans > 1)
  293.          sse2_cvtpd2ps(p->func, data, data);
  294.       else
  295.          sse2_cvtsd2ss(p->func, data, data);
  296.       if (out_chans == CHANNELS_0001)
  297.          sse_shufps(p->func, data, get_const(p, CONST_IDENTITY),
  298.                     SHUF(X, Y, Z, W));
  299.       break;
  300.    case 2:
  301.       sse2_movupd(p->func, data, arg0);
  302.       sse2_cvtpd2ps(p->func, data, data);
  303.       if (out_chans == CHANNELS_0001)
  304.          sse_shufps(p->func, data, get_const(p, CONST_IDENTITY),
  305.                     SHUF(X, Y, Z, W));
  306.       else if (out_chans > 2)
  307.          sse_movlhps(p->func, data, get_const(p, CONST_IDENTITY));
  308.       break;
  309.    case 3:
  310.       sse2_movupd(p->func, data, arg0);
  311.       sse2_cvtpd2ps(p->func, data, data);
  312.       sse2_movsd(p->func, tmpXMM, x86_make_disp(arg0, 16));
  313.       if (out_chans > 3)
  314.          sse2_cvtpd2ps(p->func, tmpXMM, tmpXMM);
  315.       else
  316.          sse2_cvtsd2ss(p->func, tmpXMM, tmpXMM);
  317.       sse_movlhps(p->func, data, tmpXMM);
  318.       if (out_chans == CHANNELS_0001)
  319.          sse_orps(p->func, data, get_const(p, CONST_IDENTITY));
  320.       break;
  321.    case 4:
  322.       sse2_movupd(p->func, data, arg0);
  323.       sse2_cvtpd2ps(p->func, data, data);
  324.       sse2_movupd(p->func, tmpXMM, x86_make_disp(arg0, 16));
  325.       sse2_cvtpd2ps(p->func, tmpXMM, tmpXMM);
  326.       sse_movlhps(p->func, data, tmpXMM);
  327.       break;
  328.    }
  329. }
  330.  
  331.  
  332. static void
  333. emit_mov64(struct translate_sse *p, struct x86_reg dst_gpr,
  334.            struct x86_reg dst_xmm, struct x86_reg src_gpr,
  335.            struct x86_reg src_xmm)
  336. {
  337.    if (x86_target(p->func) != X86_32)
  338.       x64_mov64(p->func, dst_gpr, src_gpr);
  339.    else {
  340.       /* TODO: when/on which CPUs is SSE2 actually better than SSE? */
  341.       if (x86_target_caps(p->func) & X86_SSE2)
  342.          sse2_movq(p->func, dst_xmm, src_xmm);
  343.       else
  344.          sse_movlps(p->func, dst_xmm, src_xmm);
  345.    }
  346. }
  347.  
  348.  
  349. static void
  350. emit_load64(struct translate_sse *p, struct x86_reg dst_gpr,
  351.             struct x86_reg dst_xmm, struct x86_reg src)
  352. {
  353.    emit_mov64(p, dst_gpr, dst_xmm, src, src);
  354. }
  355.  
  356.  
  357. static void
  358. emit_store64(struct translate_sse *p, struct x86_reg dst,
  359.              struct x86_reg src_gpr, struct x86_reg src_xmm)
  360. {
  361.    emit_mov64(p, dst, dst, src_gpr, src_xmm);
  362. }
  363.  
  364.  
  365. static void
  366. emit_mov128(struct translate_sse *p, struct x86_reg dst, struct x86_reg src)
  367. {
  368.    if (x86_target_caps(p->func) & X86_SSE2)
  369.       sse2_movdqu(p->func, dst, src);
  370.    else
  371.       sse_movups(p->func, dst, src);
  372. }
  373.  
  374.  
  375. /* TODO: this uses unaligned accesses liberally, which is great on Nehalem,
  376.  * but may or may not be good on older processors
  377.  * TODO: may perhaps want to use non-temporal stores here if possible
  378.  */
  379. static void
  380. emit_memcpy(struct translate_sse *p, struct x86_reg dst, struct x86_reg src,
  381.             unsigned size)
  382. {
  383.    struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
  384.    struct x86_reg dataXMM2 = x86_make_reg(file_XMM, 1);
  385.    struct x86_reg dataGPR = p->tmp_EAX;
  386.    struct x86_reg dataGPR2 = p->tmp2_EDX;
  387.  
  388.    if (size < 8) {
  389.       switch (size) {
  390.       case 1:
  391.          x86_mov8(p->func, dataGPR, src);
  392.          x86_mov8(p->func, dst, dataGPR);
  393.          break;
  394.       case 2:
  395.          x86_mov16(p->func, dataGPR, src);
  396.          x86_mov16(p->func, dst, dataGPR);
  397.          break;
  398.       case 3:
  399.          x86_mov16(p->func, dataGPR, src);
  400.          x86_mov8(p->func, dataGPR2, x86_make_disp(src, 2));
  401.          x86_mov16(p->func, dst, dataGPR);
  402.          x86_mov8(p->func, x86_make_disp(dst, 2), dataGPR2);
  403.          break;
  404.       case 4:
  405.          x86_mov(p->func, dataGPR, src);
  406.          x86_mov(p->func, dst, dataGPR);
  407.          break;
  408.       case 6:
  409.          x86_mov(p->func, dataGPR, src);
  410.          x86_mov16(p->func, dataGPR2, x86_make_disp(src, 4));
  411.          x86_mov(p->func, dst, dataGPR);
  412.          x86_mov16(p->func, x86_make_disp(dst, 4), dataGPR2);
  413.          break;
  414.       }
  415.    }
  416.    else if (!(x86_target_caps(p->func) & X86_SSE)) {
  417.       unsigned i = 0;
  418.       assert((size & 3) == 0);
  419.       for (i = 0; i < size; i += 4) {
  420.          x86_mov(p->func, dataGPR, x86_make_disp(src, i));
  421.          x86_mov(p->func, x86_make_disp(dst, i), dataGPR);
  422.       }
  423.    }
  424.    else {
  425.       switch (size) {
  426.       case 8:
  427.          emit_load64(p, dataGPR, dataXMM, src);
  428.          emit_store64(p, dst, dataGPR, dataXMM);
  429.          break;
  430.       case 12:
  431.          emit_load64(p, dataGPR2, dataXMM, src);
  432.          x86_mov(p->func, dataGPR, x86_make_disp(src, 8));
  433.          emit_store64(p, dst, dataGPR2, dataXMM);
  434.          x86_mov(p->func, x86_make_disp(dst, 8), dataGPR);
  435.          break;
  436.       case 16:
  437.          emit_mov128(p, dataXMM, src);
  438.          emit_mov128(p, dst, dataXMM);
  439.          break;
  440.       case 24:
  441.          emit_mov128(p, dataXMM, src);
  442.          emit_load64(p, dataGPR, dataXMM2, x86_make_disp(src, 16));
  443.          emit_mov128(p, dst, dataXMM);
  444.          emit_store64(p, x86_make_disp(dst, 16), dataGPR, dataXMM2);
  445.          break;
  446.       case 32:
  447.          emit_mov128(p, dataXMM, src);
  448.          emit_mov128(p, dataXMM2, x86_make_disp(src, 16));
  449.          emit_mov128(p, dst, dataXMM);
  450.          emit_mov128(p, x86_make_disp(dst, 16), dataXMM2);
  451.          break;
  452.       default:
  453.          assert(0);
  454.       }
  455.    }
  456. }
  457.  
  458. static boolean
  459. translate_attr_convert(struct translate_sse *p,
  460.                        const struct translate_element *a,
  461.                        struct x86_reg src, struct x86_reg dst)
  462. {
  463.    const struct util_format_description *input_desc =
  464.       util_format_description(a->input_format);
  465.    const struct util_format_description *output_desc =
  466.       util_format_description(a->output_format);
  467.    unsigned i;
  468.    boolean id_swizzle = TRUE;
  469.    unsigned swizzle[4] =
  470.       { UTIL_FORMAT_SWIZZLE_NONE, UTIL_FORMAT_SWIZZLE_NONE,
  471.         UTIL_FORMAT_SWIZZLE_NONE, UTIL_FORMAT_SWIZZLE_NONE };
  472.    unsigned needed_chans = 0;
  473.    unsigned imms[2] = { 0, 0x3f800000 };
  474.  
  475.    if (a->output_format == PIPE_FORMAT_NONE
  476.        || a->input_format == PIPE_FORMAT_NONE)
  477.       return FALSE;
  478.  
  479.    if (input_desc->channel[0].size & 7)
  480.       return FALSE;
  481.  
  482.    if (input_desc->colorspace != output_desc->colorspace)
  483.       return FALSE;
  484.  
  485.    for (i = 1; i < input_desc->nr_channels; ++i) {
  486.       if (memcmp
  487.           (&input_desc->channel[i], &input_desc->channel[0],
  488.            sizeof(input_desc->channel[0])))
  489.          return FALSE;
  490.    }
  491.  
  492.    for (i = 1; i < output_desc->nr_channels; ++i) {
  493.       if (memcmp
  494.           (&output_desc->channel[i], &output_desc->channel[0],
  495.            sizeof(output_desc->channel[0]))) {
  496.          return FALSE;
  497.       }
  498.    }
  499.  
  500.    for (i = 0; i < output_desc->nr_channels; ++i) {
  501.       if (output_desc->swizzle[i] < 4)
  502.          swizzle[output_desc->swizzle[i]] = input_desc->swizzle[i];
  503.    }
  504.  
  505.    if ((x86_target_caps(p->func) & X86_SSE) &&
  506.        (0 || a->output_format == PIPE_FORMAT_R32_FLOAT
  507.         || a->output_format == PIPE_FORMAT_R32G32_FLOAT
  508.         || a->output_format == PIPE_FORMAT_R32G32B32_FLOAT
  509.         || a->output_format == PIPE_FORMAT_R32G32B32A32_FLOAT)) {
  510.       struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
  511.  
  512.       for (i = 0; i < output_desc->nr_channels; ++i) {
  513.          if (swizzle[i] == UTIL_FORMAT_SWIZZLE_0
  514.              && i >= input_desc->nr_channels)
  515.             swizzle[i] = i;
  516.       }
  517.  
  518.       for (i = 0; i < output_desc->nr_channels; ++i) {
  519.          if (swizzle[i] < 4)
  520.             needed_chans = MAX2(needed_chans, swizzle[i] + 1);
  521.          if (swizzle[i] < UTIL_FORMAT_SWIZZLE_0 && swizzle[i] != i)
  522.             id_swizzle = FALSE;
  523.       }
  524.  
  525.       if (needed_chans > 0) {
  526.          switch (input_desc->channel[0].type) {
  527.          case UTIL_FORMAT_TYPE_UNSIGNED:
  528.             if (!(x86_target_caps(p->func) & X86_SSE2))
  529.                return FALSE;
  530.             emit_load_sse2(p, dataXMM, src,
  531.                            input_desc->channel[0].size *
  532.                            input_desc->nr_channels >> 3);
  533.  
  534.             /* TODO: add support for SSE4.1 pmovzx */
  535.             switch (input_desc->channel[0].size) {
  536.             case 8:
  537.                /* TODO: this may be inefficient due to get_identity() being
  538.                 *  used both as a float and integer register.
  539.                 */
  540.                sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
  541.                sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
  542.                break;
  543.             case 16:
  544.                sse2_punpcklwd(p->func, dataXMM, get_const(p, CONST_IDENTITY));
  545.                break;
  546.             case 32:           /* we lose precision here */
  547.                sse2_psrld_imm(p->func, dataXMM, 1);
  548.                break;
  549.             default:
  550.                return FALSE;
  551.             }
  552.             sse2_cvtdq2ps(p->func, dataXMM, dataXMM);
  553.             if (input_desc->channel[0].normalized) {
  554.                struct x86_reg factor;
  555.                switch (input_desc->channel[0].size) {
  556.                case 8:
  557.                   factor = get_const(p, CONST_INV_255);
  558.                   break;
  559.                case 16:
  560.                   factor = get_const(p, CONST_INV_65535);
  561.                   break;
  562.                case 32:
  563.                   factor = get_const(p, CONST_INV_2147483647);
  564.                   break;
  565.                default:
  566.                   assert(0);
  567.                   factor.disp = 0;
  568.                   factor.file = 0;
  569.                   factor.idx = 0;
  570.                   factor.mod = 0;
  571.                   break;
  572.                }
  573.                sse_mulps(p->func, dataXMM, factor);
  574.             }
  575.             else if (input_desc->channel[0].size == 32)
  576.                /* compensate for the bit we threw away to fit u32 into s32 */
  577.                sse_addps(p->func, dataXMM, dataXMM);
  578.             break;
  579.          case UTIL_FORMAT_TYPE_SIGNED:
  580.             if (!(x86_target_caps(p->func) & X86_SSE2))
  581.                return FALSE;
  582.             emit_load_sse2(p, dataXMM, src,
  583.                            input_desc->channel[0].size *
  584.                            input_desc->nr_channels >> 3);
  585.  
  586.             /* TODO: add support for SSE4.1 pmovsx */
  587.             switch (input_desc->channel[0].size) {
  588.             case 8:
  589.                sse2_punpcklbw(p->func, dataXMM, dataXMM);
  590.                sse2_punpcklbw(p->func, dataXMM, dataXMM);
  591.                sse2_psrad_imm(p->func, dataXMM, 24);
  592.                break;
  593.             case 16:
  594.                sse2_punpcklwd(p->func, dataXMM, dataXMM);
  595.                sse2_psrad_imm(p->func, dataXMM, 16);
  596.                break;
  597.             case 32:           /* we lose precision here */
  598.                break;
  599.             default:
  600.                return FALSE;
  601.             }
  602.             sse2_cvtdq2ps(p->func, dataXMM, dataXMM);
  603.             if (input_desc->channel[0].normalized) {
  604.                struct x86_reg factor;
  605.                switch (input_desc->channel[0].size) {
  606.                case 8:
  607.                   factor = get_const(p, CONST_INV_127);
  608.                   break;
  609.                case 16:
  610.                   factor = get_const(p, CONST_INV_32767);
  611.                   break;
  612.                case 32:
  613.                   factor = get_const(p, CONST_INV_2147483647);
  614.                   break;
  615.                default:
  616.                   assert(0);
  617.                   factor.disp = 0;
  618.                   factor.file = 0;
  619.                   factor.idx = 0;
  620.                   factor.mod = 0;
  621.                   break;
  622.                }
  623.                sse_mulps(p->func, dataXMM, factor);
  624.             }
  625.             break;
  626.  
  627.             break;
  628.          case UTIL_FORMAT_TYPE_FLOAT:
  629.             if (input_desc->channel[0].size != 32
  630.                 && input_desc->channel[0].size != 64) {
  631.                return FALSE;
  632.             }
  633.             if (swizzle[3] == UTIL_FORMAT_SWIZZLE_1
  634.                 && input_desc->nr_channels <= 3) {
  635.                swizzle[3] = UTIL_FORMAT_SWIZZLE_W;
  636.                needed_chans = CHANNELS_0001;
  637.             }
  638.             switch (input_desc->channel[0].size) {
  639.             case 32:
  640.                emit_load_float32(p, dataXMM, src, needed_chans,
  641.                                  input_desc->nr_channels);
  642.                break;
  643.             case 64:           /* we lose precision here */
  644.                if (!(x86_target_caps(p->func) & X86_SSE2))
  645.                   return FALSE;
  646.                emit_load_float64to32(p, dataXMM, src, needed_chans,
  647.                                      input_desc->nr_channels);
  648.                break;
  649.             default:
  650.                return FALSE;
  651.             }
  652.             break;
  653.          default:
  654.             return FALSE;
  655.          }
  656.  
  657.          if (!id_swizzle) {
  658.             sse_shufps(p->func, dataXMM, dataXMM,
  659.                        SHUF(swizzle[0], swizzle[1], swizzle[2], swizzle[3]));
  660.          }
  661.       }
  662.  
  663.       if (output_desc->nr_channels >= 4
  664.           && swizzle[0] < UTIL_FORMAT_SWIZZLE_0
  665.           && swizzle[1] < UTIL_FORMAT_SWIZZLE_0
  666.           && swizzle[2] < UTIL_FORMAT_SWIZZLE_0
  667.           && swizzle[3] < UTIL_FORMAT_SWIZZLE_0) {
  668.          sse_movups(p->func, dst, dataXMM);
  669.       }
  670.       else {
  671.          if (output_desc->nr_channels >= 2
  672.              && swizzle[0] < UTIL_FORMAT_SWIZZLE_0
  673.              && swizzle[1] < UTIL_FORMAT_SWIZZLE_0) {
  674.             sse_movlps(p->func, dst, dataXMM);
  675.          }
  676.          else {
  677.             if (swizzle[0] < UTIL_FORMAT_SWIZZLE_0) {
  678.                sse_movss(p->func, dst, dataXMM);
  679.             }
  680.             else {
  681.                x86_mov_imm(p->func, dst,
  682.                            imms[swizzle[0] - UTIL_FORMAT_SWIZZLE_0]);
  683.             }
  684.  
  685.             if (output_desc->nr_channels >= 2) {
  686.                if (swizzle[1] < UTIL_FORMAT_SWIZZLE_0) {
  687.                   sse_shufps(p->func, dataXMM, dataXMM, SHUF(1, 1, 2, 3));
  688.                   sse_movss(p->func, x86_make_disp(dst, 4), dataXMM);
  689.                }
  690.                else {
  691.                   x86_mov_imm(p->func, x86_make_disp(dst, 4),
  692.                               imms[swizzle[1] - UTIL_FORMAT_SWIZZLE_0]);
  693.                }
  694.             }
  695.          }
  696.  
  697.          if (output_desc->nr_channels >= 3) {
  698.             if (output_desc->nr_channels >= 4
  699.                 && swizzle[2] < UTIL_FORMAT_SWIZZLE_0
  700.                 && swizzle[3] < UTIL_FORMAT_SWIZZLE_0) {
  701.                sse_movhps(p->func, x86_make_disp(dst, 8), dataXMM);
  702.             }
  703.             else {
  704.                if (swizzle[2] < UTIL_FORMAT_SWIZZLE_0) {
  705.                   sse_shufps(p->func, dataXMM, dataXMM, SHUF(2, 2, 2, 3));
  706.                   sse_movss(p->func, x86_make_disp(dst, 8), dataXMM);
  707.                }
  708.                else {
  709.                   x86_mov_imm(p->func, x86_make_disp(dst, 8),
  710.                               imms[swizzle[2] - UTIL_FORMAT_SWIZZLE_0]);
  711.                }
  712.  
  713.                if (output_desc->nr_channels >= 4) {
  714.                   if (swizzle[3] < UTIL_FORMAT_SWIZZLE_0) {
  715.                      sse_shufps(p->func, dataXMM, dataXMM, SHUF(3, 3, 3, 3));
  716.                      sse_movss(p->func, x86_make_disp(dst, 12), dataXMM);
  717.                   }
  718.                   else {
  719.                      x86_mov_imm(p->func, x86_make_disp(dst, 12),
  720.                                  imms[swizzle[3] - UTIL_FORMAT_SWIZZLE_0]);
  721.                   }
  722.                }
  723.             }
  724.          }
  725.       }
  726.       return TRUE;
  727.    }
  728.    else if ((x86_target_caps(p->func) & X86_SSE2)
  729.             && input_desc->channel[0].size == 8
  730.             && output_desc->channel[0].size == 16
  731.             && output_desc->channel[0].normalized ==
  732.             input_desc->channel[0].normalized &&
  733.             (0 || (input_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED
  734.                    && output_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
  735.              || (input_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED
  736.                  && output_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED)
  737.              || (input_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED
  738.                  && output_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED))) {
  739.       struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
  740.       struct x86_reg tmpXMM = x86_make_reg(file_XMM, 1);
  741.       struct x86_reg tmp = p->tmp_EAX;
  742.       unsigned imms[2] = { 0, 1 };
  743.  
  744.       for (i = 0; i < output_desc->nr_channels; ++i) {
  745.          if (swizzle[i] == UTIL_FORMAT_SWIZZLE_0
  746.              && i >= input_desc->nr_channels) {
  747.             swizzle[i] = i;
  748.          }
  749.       }
  750.  
  751.       for (i = 0; i < output_desc->nr_channels; ++i) {
  752.          if (swizzle[i] < 4)
  753.             needed_chans = MAX2(needed_chans, swizzle[i] + 1);
  754.          if (swizzle[i] < UTIL_FORMAT_SWIZZLE_0 && swizzle[i] != i)
  755.             id_swizzle = FALSE;
  756.       }
  757.  
  758.       if (needed_chans > 0) {
  759.          emit_load_sse2(p, dataXMM, src,
  760.                         input_desc->channel[0].size *
  761.                         input_desc->nr_channels >> 3);
  762.  
  763.          switch (input_desc->channel[0].type) {
  764.          case UTIL_FORMAT_TYPE_UNSIGNED:
  765.             if (input_desc->channel[0].normalized) {
  766.                sse2_punpcklbw(p->func, dataXMM, dataXMM);
  767.                if (output_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED)
  768.                   sse2_psrlw_imm(p->func, dataXMM, 1);
  769.             }
  770.             else
  771.                sse2_punpcklbw(p->func, dataXMM, get_const(p, CONST_IDENTITY));
  772.             break;
  773.          case UTIL_FORMAT_TYPE_SIGNED:
  774.             if (input_desc->channel[0].normalized) {
  775.                sse2_movq(p->func, tmpXMM, get_const(p, CONST_IDENTITY));
  776.                sse2_punpcklbw(p->func, tmpXMM, dataXMM);
  777.                sse2_psllw_imm(p->func, dataXMM, 9);
  778.                sse2_psrlw_imm(p->func, dataXMM, 8);
  779.                sse2_por(p->func, tmpXMM, dataXMM);
  780.                sse2_psrlw_imm(p->func, dataXMM, 7);
  781.                sse2_por(p->func, tmpXMM, dataXMM);
  782.                {
  783.                   struct x86_reg t = dataXMM;
  784.                   dataXMM = tmpXMM;
  785.                   tmpXMM = t;
  786.                }
  787.             }
  788.             else {
  789.                sse2_punpcklbw(p->func, dataXMM, dataXMM);
  790.                sse2_psraw_imm(p->func, dataXMM, 8);
  791.             }
  792.             break;
  793.          default:
  794.             assert(0);
  795.          }
  796.  
  797.          if (output_desc->channel[0].normalized)
  798.             imms[1] =
  799.                (output_desc->channel[0].type ==
  800.                 UTIL_FORMAT_TYPE_UNSIGNED) ? 0xffff : 0x7ffff;
  801.  
  802.          if (!id_swizzle)
  803.             sse2_pshuflw(p->func, dataXMM, dataXMM,
  804.                          (swizzle[0] & 3) | ((swizzle[1] & 3) << 2) |
  805.                          ((swizzle[2] & 3) << 4) | ((swizzle[3] & 3) << 6));
  806.       }
  807.  
  808.       if (output_desc->nr_channels >= 4
  809.           && swizzle[0] < UTIL_FORMAT_SWIZZLE_0
  810.           && swizzle[1] < UTIL_FORMAT_SWIZZLE_0
  811.           && swizzle[2] < UTIL_FORMAT_SWIZZLE_0
  812.           && swizzle[3] < UTIL_FORMAT_SWIZZLE_0) {
  813.          sse2_movq(p->func, dst, dataXMM);
  814.       }
  815.       else {
  816.          if (swizzle[0] < UTIL_FORMAT_SWIZZLE_0) {
  817.             if (output_desc->nr_channels >= 2
  818.                 && swizzle[1] < UTIL_FORMAT_SWIZZLE_0) {
  819.                sse2_movd(p->func, dst, dataXMM);
  820.             }
  821.             else {
  822.                sse2_movd(p->func, tmp, dataXMM);
  823.                x86_mov16(p->func, dst, tmp);
  824.                if (output_desc->nr_channels >= 2)
  825.                   x86_mov16_imm(p->func, x86_make_disp(dst, 2),
  826.                                 imms[swizzle[1] - UTIL_FORMAT_SWIZZLE_0]);
  827.             }
  828.          }
  829.          else {
  830.             if (output_desc->nr_channels >= 2
  831.                 && swizzle[1] >= UTIL_FORMAT_SWIZZLE_0) {
  832.                x86_mov_imm(p->func, dst,
  833.                            (imms[swizzle[1] - UTIL_FORMAT_SWIZZLE_0] << 16) |
  834.                            imms[swizzle[0] - UTIL_FORMAT_SWIZZLE_0]);
  835.             }
  836.             else {
  837.                x86_mov16_imm(p->func, dst,
  838.                              imms[swizzle[0] - UTIL_FORMAT_SWIZZLE_0]);
  839.                if (output_desc->nr_channels >= 2) {
  840.                   sse2_movd(p->func, tmp, dataXMM);
  841.                   x86_shr_imm(p->func, tmp, 16);
  842.                   x86_mov16(p->func, x86_make_disp(dst, 2), tmp);
  843.                }
  844.             }
  845.          }
  846.  
  847.          if (output_desc->nr_channels >= 3) {
  848.             if (swizzle[2] < UTIL_FORMAT_SWIZZLE_0) {
  849.                if (output_desc->nr_channels >= 4
  850.                    && swizzle[3] < UTIL_FORMAT_SWIZZLE_0) {
  851.                   sse2_psrlq_imm(p->func, dataXMM, 32);
  852.                   sse2_movd(p->func, x86_make_disp(dst, 4), dataXMM);
  853.                }
  854.                else {
  855.                   sse2_psrlq_imm(p->func, dataXMM, 32);
  856.                   sse2_movd(p->func, tmp, dataXMM);
  857.                   x86_mov16(p->func, x86_make_disp(dst, 4), tmp);
  858.                   if (output_desc->nr_channels >= 4) {
  859.                      x86_mov16_imm(p->func, x86_make_disp(dst, 6),
  860.                                    imms[swizzle[3] - UTIL_FORMAT_SWIZZLE_0]);
  861.                   }
  862.                }
  863.             }
  864.             else {
  865.                if (output_desc->nr_channels >= 4
  866.                    && swizzle[3] >= UTIL_FORMAT_SWIZZLE_0) {
  867.                   x86_mov_imm(p->func, x86_make_disp(dst, 4),
  868.                               (imms[swizzle[3] - UTIL_FORMAT_SWIZZLE_0] << 16)
  869.                               | imms[swizzle[2] - UTIL_FORMAT_SWIZZLE_0]);
  870.                }
  871.                else {
  872.                   x86_mov16_imm(p->func, x86_make_disp(dst, 4),
  873.                                 imms[swizzle[2] - UTIL_FORMAT_SWIZZLE_0]);
  874.  
  875.                   if (output_desc->nr_channels >= 4) {
  876.                      sse2_psrlq_imm(p->func, dataXMM, 48);
  877.                      sse2_movd(p->func, tmp, dataXMM);
  878.                      x86_mov16(p->func, x86_make_disp(dst, 6), tmp);
  879.                   }
  880.                }
  881.             }
  882.          }
  883.       }
  884.       return TRUE;
  885.    }
  886.    else if (!memcmp(&output_desc->channel[0], &input_desc->channel[0],
  887.                     sizeof(output_desc->channel[0]))) {
  888.       struct x86_reg tmp = p->tmp_EAX;
  889.       unsigned i;
  890.  
  891.       if (input_desc->channel[0].size == 8 && input_desc->nr_channels == 4
  892.           && output_desc->nr_channels == 4
  893.           && swizzle[0] == UTIL_FORMAT_SWIZZLE_W
  894.           && swizzle[1] == UTIL_FORMAT_SWIZZLE_Z
  895.           && swizzle[2] == UTIL_FORMAT_SWIZZLE_Y
  896.           && swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
  897.          /* TODO: support movbe */
  898.          x86_mov(p->func, tmp, src);
  899.          x86_bswap(p->func, tmp);
  900.          x86_mov(p->func, dst, tmp);
  901.          return TRUE;
  902.       }
  903.  
  904.       for (i = 0; i < output_desc->nr_channels; ++i) {
  905.          switch (output_desc->channel[0].size) {
  906.          case 8:
  907.             if (swizzle[i] >= UTIL_FORMAT_SWIZZLE_0) {
  908.                unsigned v = 0;
  909.                if (swizzle[i] == UTIL_FORMAT_SWIZZLE_1) {
  910.                   switch (output_desc->channel[0].type) {
  911.                   case UTIL_FORMAT_TYPE_UNSIGNED:
  912.                      v = output_desc->channel[0].normalized ? 0xff : 1;
  913.                      break;
  914.                   case UTIL_FORMAT_TYPE_SIGNED:
  915.                      v = output_desc->channel[0].normalized ? 0x7f : 1;
  916.                      break;
  917.                   default:
  918.                      return FALSE;
  919.                   }
  920.                }
  921.                x86_mov8_imm(p->func, x86_make_disp(dst, i * 1), v);
  922.             }
  923.             else {
  924.                x86_mov8(p->func, tmp, x86_make_disp(src, swizzle[i] * 1));
  925.                x86_mov8(p->func, x86_make_disp(dst, i * 1), tmp);
  926.             }
  927.             break;
  928.          case 16:
  929.             if (swizzle[i] >= UTIL_FORMAT_SWIZZLE_0) {
  930.                unsigned v = 0;
  931.                if (swizzle[i] == UTIL_FORMAT_SWIZZLE_1) {
  932.                   switch (output_desc->channel[1].type) {
  933.                   case UTIL_FORMAT_TYPE_UNSIGNED:
  934.                      v = output_desc->channel[1].normalized ? 0xffff : 1;
  935.                      break;
  936.                   case UTIL_FORMAT_TYPE_SIGNED:
  937.                      v = output_desc->channel[1].normalized ? 0x7fff : 1;
  938.                      break;
  939.                   case UTIL_FORMAT_TYPE_FLOAT:
  940.                      v = 0x3c00;
  941.                      break;
  942.                   default:
  943.                      return FALSE;
  944.                   }
  945.                }
  946.                x86_mov16_imm(p->func, x86_make_disp(dst, i * 2), v);
  947.             }
  948.             else if (swizzle[i] == UTIL_FORMAT_SWIZZLE_0) {
  949.                x86_mov16_imm(p->func, x86_make_disp(dst, i * 2), 0);
  950.             }
  951.             else {
  952.                x86_mov16(p->func, tmp, x86_make_disp(src, swizzle[i] * 2));
  953.                x86_mov16(p->func, x86_make_disp(dst, i * 2), tmp);
  954.             }
  955.             break;
  956.          case 32:
  957.             if (swizzle[i] >= UTIL_FORMAT_SWIZZLE_0) {
  958.                unsigned v = 0;
  959.                if (swizzle[i] == UTIL_FORMAT_SWIZZLE_1) {
  960.                   switch (output_desc->channel[1].type) {
  961.                   case UTIL_FORMAT_TYPE_UNSIGNED:
  962.                      v = output_desc->channel[1].normalized ? 0xffffffff : 1;
  963.                      break;
  964.                   case UTIL_FORMAT_TYPE_SIGNED:
  965.                      v = output_desc->channel[1].normalized ? 0x7fffffff : 1;
  966.                      break;
  967.                   case UTIL_FORMAT_TYPE_FLOAT:
  968.                      v = 0x3f800000;
  969.                      break;
  970.                   default:
  971.                      return FALSE;
  972.                   }
  973.                }
  974.                x86_mov_imm(p->func, x86_make_disp(dst, i * 4), v);
  975.             }
  976.             else {
  977.                x86_mov(p->func, tmp, x86_make_disp(src, swizzle[i] * 4));
  978.                x86_mov(p->func, x86_make_disp(dst, i * 4), tmp);
  979.             }
  980.             break;
  981.          case 64:
  982.             if (swizzle[i] >= UTIL_FORMAT_SWIZZLE_0) {
  983.                unsigned l = 0;
  984.                unsigned h = 0;
  985.                if (swizzle[i] == UTIL_FORMAT_SWIZZLE_1) {
  986.                   switch (output_desc->channel[1].type) {
  987.                   case UTIL_FORMAT_TYPE_UNSIGNED:
  988.                      h = output_desc->channel[1].normalized ? 0xffffffff : 0;
  989.                      l = output_desc->channel[1].normalized ? 0xffffffff : 1;
  990.                      break;
  991.                   case UTIL_FORMAT_TYPE_SIGNED:
  992.                      h = output_desc->channel[1].normalized ? 0x7fffffff : 0;
  993.                      l = output_desc->channel[1].normalized ? 0xffffffff : 1;
  994.                      break;
  995.                   case UTIL_FORMAT_TYPE_FLOAT:
  996.                      h = 0x3ff00000;
  997.                      l = 0;
  998.                      break;
  999.                   default:
  1000.                      return FALSE;
  1001.                   }
  1002.                }
  1003.                x86_mov_imm(p->func, x86_make_disp(dst, i * 8), l);
  1004.                x86_mov_imm(p->func, x86_make_disp(dst, i * 8 + 4), h);
  1005.             }
  1006.             else {
  1007.                if (x86_target_caps(p->func) & X86_SSE) {
  1008.                   struct x86_reg tmpXMM = x86_make_reg(file_XMM, 0);
  1009.                   emit_load64(p, tmp, tmpXMM,
  1010.                               x86_make_disp(src, swizzle[i] * 8));
  1011.                   emit_store64(p, x86_make_disp(dst, i * 8), tmp, tmpXMM);
  1012.                }
  1013.                else {
  1014.                   x86_mov(p->func, tmp, x86_make_disp(src, swizzle[i] * 8));
  1015.                   x86_mov(p->func, x86_make_disp(dst, i * 8), tmp);
  1016.                   x86_mov(p->func, tmp,
  1017.                           x86_make_disp(src, swizzle[i] * 8 + 4));
  1018.                   x86_mov(p->func, x86_make_disp(dst, i * 8 + 4), tmp);
  1019.                }
  1020.             }
  1021.             break;
  1022.          default:
  1023.             return FALSE;
  1024.          }
  1025.       }
  1026.       return TRUE;
  1027.    }
  1028.    /* special case for draw's EMIT_4UB (RGBA) and EMIT_4UB_BGRA */
  1029.    else if ((x86_target_caps(p->func) & X86_SSE2) &&
  1030.             a->input_format == PIPE_FORMAT_R32G32B32A32_FLOAT &&
  1031.             (0 || a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM
  1032.              || a-> output_format == PIPE_FORMAT_R8G8B8A8_UNORM)) {
  1033.       struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
  1034.  
  1035.       /* load */
  1036.       sse_movups(p->func, dataXMM, src);
  1037.  
  1038.       if (a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM) {
  1039.          sse_shufps(p->func, dataXMM, dataXMM, SHUF(2, 1, 0, 3));
  1040.       }
  1041.  
  1042.       /* scale by 255.0 */
  1043.       sse_mulps(p->func, dataXMM, get_const(p, CONST_255));
  1044.  
  1045.       /* pack and emit */
  1046.       sse2_cvtps2dq(p->func, dataXMM, dataXMM);
  1047.       sse2_packssdw(p->func, dataXMM, dataXMM);
  1048.       sse2_packuswb(p->func, dataXMM, dataXMM);
  1049.       sse2_movd(p->func, dst, dataXMM);
  1050.  
  1051.       return TRUE;
  1052.    }
  1053.  
  1054.    return FALSE;
  1055. }
  1056.  
  1057.  
  1058. static boolean
  1059. translate_attr(struct translate_sse *p,
  1060.                const struct translate_element *a,
  1061.                struct x86_reg src, struct x86_reg dst)
  1062. {
  1063.    if (a->input_format == a->output_format) {
  1064.       emit_memcpy(p, dst, src, util_format_get_stride(a->input_format, 1));
  1065.       return TRUE;
  1066.    }
  1067.  
  1068.    return translate_attr_convert(p, a, src, dst);
  1069. }
  1070.  
  1071.  
  1072. static boolean
  1073. init_inputs(struct translate_sse *p, unsigned index_size)
  1074. {
  1075.    unsigned i;
  1076.    struct x86_reg instance_id =
  1077.       x86_make_disp(p->machine_EDI, get_offset(p, &p->instance_id));
  1078.    struct x86_reg start_instance =
  1079.       x86_make_disp(p->machine_EDI, get_offset(p, &p->start_instance));
  1080.  
  1081.    for (i = 0; i < p->nr_buffer_variants; i++) {
  1082.       struct translate_buffer_variant *variant = &p->buffer_variant[i];
  1083.       struct translate_buffer *buffer = &p->buffer[variant->buffer_index];
  1084.  
  1085.       if (!index_size || variant->instance_divisor) {
  1086.          struct x86_reg buf_max_index =
  1087.             x86_make_disp(p->machine_EDI, get_offset(p, &buffer->max_index));
  1088.          struct x86_reg buf_stride =
  1089.             x86_make_disp(p->machine_EDI, get_offset(p, &buffer->stride));
  1090.          struct x86_reg buf_ptr =
  1091.             x86_make_disp(p->machine_EDI, get_offset(p, &variant->ptr));
  1092.          struct x86_reg buf_base_ptr =
  1093.             x86_make_disp(p->machine_EDI, get_offset(p, &buffer->base_ptr));
  1094.          struct x86_reg elt = p->idx_ESI;
  1095.          struct x86_reg tmp_EAX = p->tmp_EAX;
  1096.  
  1097.          /* Calculate pointer to first attrib:
  1098.           *   base_ptr + stride * index, where index depends on instance divisor
  1099.           */
  1100.          if (variant->instance_divisor) {
  1101.             /* Start with instance = instance_id
  1102.              * which is true if divisor is 1.
  1103.              */
  1104.             x86_mov(p->func, tmp_EAX, instance_id);
  1105.  
  1106.             if (variant->instance_divisor != 1) {
  1107.                struct x86_reg tmp_EDX = p->tmp2_EDX;
  1108.                struct x86_reg tmp_ECX = p->src_ECX;
  1109.  
  1110.                /* TODO: Add x86_shr() to rtasm and use it whenever
  1111.                 *       instance divisor is power of two.
  1112.                 */
  1113.                x86_xor(p->func, tmp_EDX, tmp_EDX);
  1114.                x86_mov_reg_imm(p->func, tmp_ECX, variant->instance_divisor);
  1115.                x86_div(p->func, tmp_ECX);       /* EAX = EDX:EAX / ECX */
  1116.  
  1117.                /* instance = (instance_id - start_instance) / divisor +
  1118.                 *             start_instance
  1119.                 */
  1120.                x86_mov(p->func, tmp_EDX, start_instance);
  1121.                x86_add(p->func, tmp_EAX, tmp_EDX);
  1122.             }
  1123.  
  1124.             /* XXX we need to clamp the index here too, but to a
  1125.              * per-array max value, not the draw->pt.max_index value
  1126.              * that's being given to us via translate->set_buffer().
  1127.              */
  1128.          }
  1129.          else {
  1130.             x86_mov(p->func, tmp_EAX, elt);
  1131.  
  1132.             /* Clamp to max_index
  1133.              */
  1134.             x86_cmp(p->func, tmp_EAX, buf_max_index);
  1135.             x86_cmovcc(p->func, tmp_EAX, buf_max_index, cc_AE);
  1136.          }
  1137.  
  1138.          x86_mov(p->func, p->tmp2_EDX, buf_stride);
  1139.          x64_rexw(p->func);
  1140.          x86_imul(p->func, tmp_EAX, p->tmp2_EDX);
  1141.          x64_rexw(p->func);
  1142.          x86_add(p->func, tmp_EAX, buf_base_ptr);
  1143.  
  1144.          x86_cmp(p->func, p->count_EBP, p->tmp_EAX);
  1145.  
  1146.          /* In the linear case, keep the buffer pointer instead of the
  1147.           * index number.
  1148.           */
  1149.          if (!index_size && p->nr_buffer_variants == 1) {
  1150.             x64_rexw(p->func);
  1151.             x86_mov(p->func, elt, tmp_EAX);
  1152.          }
  1153.          else {
  1154.             x64_rexw(p->func);
  1155.             x86_mov(p->func, buf_ptr, tmp_EAX);
  1156.          }
  1157.       }
  1158.    }
  1159.  
  1160.    return TRUE;
  1161. }
  1162.  
  1163.  
  1164. static struct x86_reg
  1165. get_buffer_ptr(struct translate_sse *p,
  1166.                unsigned index_size, unsigned var_idx, struct x86_reg elt)
  1167. {
  1168.    if (var_idx == ELEMENT_BUFFER_INSTANCE_ID) {
  1169.       return x86_make_disp(p->machine_EDI, get_offset(p, &p->instance_id));
  1170.    }
  1171.    if (!index_size && p->nr_buffer_variants == 1) {
  1172.       return p->idx_ESI;
  1173.    }
  1174.    else if (!index_size || p->buffer_variant[var_idx].instance_divisor) {
  1175.       struct x86_reg ptr = p->src_ECX;
  1176.       struct x86_reg buf_ptr =
  1177.          x86_make_disp(p->machine_EDI,
  1178.                        get_offset(p, &p->buffer_variant[var_idx].ptr));
  1179.  
  1180.       x64_rexw(p->func);
  1181.       x86_mov(p->func, ptr, buf_ptr);
  1182.       return ptr;
  1183.    }
  1184.    else {
  1185.       struct x86_reg ptr = p->src_ECX;
  1186.       const struct translate_buffer_variant *variant =
  1187.          &p->buffer_variant[var_idx];
  1188.       struct x86_reg buf_stride =
  1189.          x86_make_disp(p->machine_EDI,
  1190.                        get_offset(p, &p->buffer[variant->buffer_index].stride));
  1191.       struct x86_reg buf_base_ptr =
  1192.          x86_make_disp(p->machine_EDI,
  1193.                   get_offset(p, &p->buffer[variant->buffer_index].base_ptr));
  1194.       struct x86_reg buf_max_index =
  1195.          x86_make_disp(p->machine_EDI,
  1196.                   get_offset(p, &p->buffer[variant->buffer_index].max_index));
  1197.  
  1198.       /* Calculate pointer to current attrib:
  1199.        */
  1200.       switch (index_size) {
  1201.       case 1:
  1202.          x86_movzx8(p->func, ptr, elt);
  1203.          break;
  1204.       case 2:
  1205.          x86_movzx16(p->func, ptr, elt);
  1206.          break;
  1207.       case 4:
  1208.          x86_mov(p->func, ptr, elt);
  1209.          break;
  1210.       }
  1211.  
  1212.       /* Clamp to max_index
  1213.        */
  1214.       x86_cmp(p->func, ptr, buf_max_index);
  1215.       x86_cmovcc(p->func, ptr, buf_max_index, cc_AE);
  1216.  
  1217.       x86_mov(p->func, p->tmp2_EDX, buf_stride);
  1218.       x64_rexw(p->func);
  1219.       x86_imul(p->func, ptr, p->tmp2_EDX);
  1220.       x64_rexw(p->func);
  1221.       x86_add(p->func, ptr, buf_base_ptr);
  1222.       return ptr;
  1223.    }
  1224. }
  1225.  
  1226.  
  1227. static boolean
  1228. incr_inputs(struct translate_sse *p, unsigned index_size)
  1229. {
  1230.    if (!index_size && p->nr_buffer_variants == 1) {
  1231.       const unsigned buffer_index = p->buffer_variant[0].buffer_index;
  1232.       struct x86_reg stride =
  1233.          x86_make_disp(p->machine_EDI,
  1234.                        get_offset(p, &p->buffer[buffer_index].stride));
  1235.  
  1236.       if (p->buffer_variant[0].instance_divisor == 0) {
  1237.          x64_rexw(p->func);
  1238.          x86_add(p->func, p->idx_ESI, stride);
  1239.          sse_prefetchnta(p->func, x86_make_disp(p->idx_ESI, 192));
  1240.       }
  1241.    }
  1242.    else if (!index_size) {
  1243.       unsigned i;
  1244.  
  1245.       /* Is this worthwhile??
  1246.        */
  1247.       for (i = 0; i < p->nr_buffer_variants; i++) {
  1248.          struct translate_buffer_variant *variant = &p->buffer_variant[i];
  1249.          struct x86_reg buf_ptr = x86_make_disp(p->machine_EDI,
  1250.                                                 get_offset(p, &variant->ptr));
  1251.       struct x86_reg buf_stride =
  1252.          x86_make_disp(p->machine_EDI,
  1253.                        get_offset(p, &p->buffer[variant->buffer_index].stride));
  1254.  
  1255.          if (variant->instance_divisor == 0) {
  1256.             x86_mov(p->func, p->tmp_EAX, buf_stride);
  1257.             x64_rexw(p->func);
  1258.             x86_add(p->func, p->tmp_EAX, buf_ptr);
  1259.             if (i == 0)
  1260.                sse_prefetchnta(p->func, x86_make_disp(p->tmp_EAX, 192));
  1261.             x64_rexw(p->func);
  1262.             x86_mov(p->func, buf_ptr, p->tmp_EAX);
  1263.          }
  1264.       }
  1265.    }
  1266.    else {
  1267.       x64_rexw(p->func);
  1268.       x86_lea(p->func, p->idx_ESI, x86_make_disp(p->idx_ESI, index_size));
  1269.    }
  1270.  
  1271.    return TRUE;
  1272. }
  1273.  
  1274.  
  1275. /* Build run( struct translate *machine,
  1276.  *            unsigned start,
  1277.  *            unsigned count,
  1278.  *            void *output_buffer )
  1279.  * or
  1280.  *  run_elts( struct translate *machine,
  1281.  *            unsigned *elts,
  1282.  *            unsigned count,
  1283.  *            void *output_buffer )
  1284.  *
  1285.  *  Lots of hardcoding
  1286.  *
  1287.  * EAX -- pointer to current output vertex
  1288.  * ECX -- pointer to current attribute
  1289.  *
  1290.  */
  1291. static boolean
  1292. build_vertex_emit(struct translate_sse *p,
  1293.                   struct x86_function *func, unsigned index_size)
  1294. {
  1295.    int fixup, label;
  1296.    unsigned j;
  1297.  
  1298.    memset(p->reg_to_const, 0xff, sizeof(p->reg_to_const));
  1299.    memset(p->const_to_reg, 0xff, sizeof(p->const_to_reg));
  1300.  
  1301.    p->tmp_EAX = x86_make_reg(file_REG32, reg_AX);
  1302.    p->idx_ESI = x86_make_reg(file_REG32, reg_SI);
  1303.    p->outbuf_EBX = x86_make_reg(file_REG32, reg_BX);
  1304.    p->machine_EDI = x86_make_reg(file_REG32, reg_DI);
  1305.    p->count_EBP = x86_make_reg(file_REG32, reg_BP);
  1306.    p->tmp2_EDX = x86_make_reg(file_REG32, reg_DX);
  1307.    p->src_ECX = x86_make_reg(file_REG32, reg_CX);
  1308.  
  1309.    p->func = func;
  1310.  
  1311.    x86_init_func(p->func);
  1312.  
  1313.    if (x86_target(p->func) == X86_64_WIN64_ABI) {
  1314.       /* the ABI guarantees a 16-byte aligned 32-byte "shadow space"
  1315.        * above the return address
  1316.        */
  1317.       sse2_movdqa(p->func, x86_make_disp(x86_make_reg(file_REG32, reg_SP), 8),
  1318.                   x86_make_reg(file_XMM, 6));
  1319.       sse2_movdqa(p->func,
  1320.                   x86_make_disp(x86_make_reg(file_REG32, reg_SP), 24),
  1321.                   x86_make_reg(file_XMM, 7));
  1322.    }
  1323.  
  1324.    x86_push(p->func, p->outbuf_EBX);
  1325.    x86_push(p->func, p->count_EBP);
  1326.  
  1327.    /* on non-Win64 x86-64, these are already in the right registers */
  1328.    if (x86_target(p->func) != X86_64_STD_ABI) {
  1329.       x86_push(p->func, p->machine_EDI);
  1330.       x86_push(p->func, p->idx_ESI);
  1331.  
  1332.       if (x86_target(p->func) != X86_32) {
  1333.          x64_mov64(p->func, p->machine_EDI, x86_fn_arg(p->func, 1));
  1334.          x64_mov64(p->func, p->idx_ESI, x86_fn_arg(p->func, 2));
  1335.       }
  1336.       else {
  1337.          x86_mov(p->func, p->machine_EDI, x86_fn_arg(p->func, 1));
  1338.          x86_mov(p->func, p->idx_ESI, x86_fn_arg(p->func, 2));
  1339.       }
  1340.    }
  1341.  
  1342.    x86_mov(p->func, p->count_EBP, x86_fn_arg(p->func, 3));
  1343.  
  1344.    if (x86_target(p->func) != X86_32)
  1345.       x64_mov64(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 6));
  1346.    else
  1347.       x86_mov(p->func, p->outbuf_EBX, x86_fn_arg(p->func, 6));
  1348.  
  1349.    /* Load instance ID.
  1350.     */
  1351.    if (p->use_instancing) {
  1352.       x86_mov(p->func, p->tmp2_EDX, x86_fn_arg(p->func, 4));
  1353.       x86_mov(p->func,
  1354.               x86_make_disp(p->machine_EDI,
  1355.                             get_offset(p, &p->start_instance)), p->tmp2_EDX);
  1356.  
  1357.       x86_mov(p->func, p->tmp_EAX, x86_fn_arg(p->func, 5));
  1358.       x86_mov(p->func,
  1359.               x86_make_disp(p->machine_EDI, get_offset(p, &p->instance_id)),
  1360.               p->tmp_EAX);
  1361.    }
  1362.  
  1363.    /* Get vertex count, compare to zero
  1364.     */
  1365.    x86_xor(p->func, p->tmp_EAX, p->tmp_EAX);
  1366.    x86_cmp(p->func, p->count_EBP, p->tmp_EAX);
  1367.    fixup = x86_jcc_forward(p->func, cc_E);
  1368.  
  1369.    /* always load, needed or not:
  1370.     */
  1371.    init_inputs(p, index_size);
  1372.  
  1373.    /* Note address for loop jump
  1374.     */
  1375.    label = x86_get_label(p->func);
  1376.    {
  1377.       struct x86_reg elt = !index_size ? p->idx_ESI : x86_deref(p->idx_ESI);
  1378.       int last_variant = -1;
  1379.       struct x86_reg vb;
  1380.  
  1381.       for (j = 0; j < p->translate.key.nr_elements; j++) {
  1382.          const struct translate_element *a = &p->translate.key.element[j];
  1383.          unsigned variant = p->element_to_buffer_variant[j];
  1384.  
  1385.          /* Figure out source pointer address:
  1386.           */
  1387.          if (variant != last_variant) {
  1388.             last_variant = variant;
  1389.             vb = get_buffer_ptr(p, index_size, variant, elt);
  1390.          }
  1391.  
  1392.          if (!translate_attr(p, a,
  1393.                              x86_make_disp(vb, a->input_offset),
  1394.                              x86_make_disp(p->outbuf_EBX, a->output_offset)))
  1395.             return FALSE;
  1396.       }
  1397.  
  1398.       /* Next output vertex:
  1399.        */
  1400.       x64_rexw(p->func);
  1401.       x86_lea(p->func, p->outbuf_EBX,
  1402.               x86_make_disp(p->outbuf_EBX, p->translate.key.output_stride));
  1403.  
  1404.       /* Incr index
  1405.        */
  1406.       incr_inputs(p, index_size);
  1407.    }
  1408.  
  1409.    /* decr count, loop if not zero
  1410.     */
  1411.    x86_dec(p->func, p->count_EBP);
  1412.    x86_jcc(p->func, cc_NZ, label);
  1413.  
  1414.    /* Exit mmx state?
  1415.     */
  1416.    if (p->func->need_emms)
  1417.       mmx_emms(p->func);
  1418.  
  1419.    /* Land forward jump here:
  1420.     */
  1421.    x86_fixup_fwd_jump(p->func, fixup);
  1422.  
  1423.    /* Pop regs and return
  1424.     */
  1425.    if (x86_target(p->func) != X86_64_STD_ABI) {
  1426.       x86_pop(p->func, p->idx_ESI);
  1427.       x86_pop(p->func, p->machine_EDI);
  1428.    }
  1429.  
  1430.    x86_pop(p->func, p->count_EBP);
  1431.    x86_pop(p->func, p->outbuf_EBX);
  1432.  
  1433.    if (x86_target(p->func) == X86_64_WIN64_ABI) {
  1434.       sse2_movdqa(p->func, x86_make_reg(file_XMM, 6),
  1435.                   x86_make_disp(x86_make_reg(file_REG32, reg_SP), 8));
  1436.       sse2_movdqa(p->func, x86_make_reg(file_XMM, 7),
  1437.                   x86_make_disp(x86_make_reg(file_REG32, reg_SP), 24));
  1438.    }
  1439.    x86_ret(p->func);
  1440.  
  1441.    return TRUE;
  1442. }
  1443.  
  1444.  
  1445. static void
  1446. translate_sse_set_buffer(struct translate *translate,
  1447.                          unsigned buf,
  1448.                          const void *ptr, unsigned stride, unsigned max_index)
  1449. {
  1450.    struct translate_sse *p = (struct translate_sse *) translate;
  1451.  
  1452.    if (buf < p->nr_buffers) {
  1453.       p->buffer[buf].base_ptr = (char *) ptr;
  1454.       p->buffer[buf].stride = stride;
  1455.       p->buffer[buf].max_index = max_index;
  1456.    }
  1457.  
  1458.    if (0)
  1459.       debug_printf("%s %d/%d: %p %d\n",
  1460.                    __FUNCTION__, buf, p->nr_buffers, ptr, stride);
  1461. }
  1462.  
  1463.  
  1464. static void
  1465. translate_sse_release(struct translate *translate)
  1466. {
  1467.    struct translate_sse *p = (struct translate_sse *) translate;
  1468.  
  1469.    x86_release_func(&p->elt8_func);
  1470.    x86_release_func(&p->elt16_func);
  1471.    x86_release_func(&p->elt_func);
  1472.    x86_release_func(&p->linear_func);
  1473.  
  1474.    os_free_aligned(p);
  1475. }
  1476.  
  1477.  
  1478. struct translate *
  1479. translate_sse2_create(const struct translate_key *key)
  1480. {
  1481.    struct translate_sse *p = NULL;
  1482.    unsigned i;
  1483.  
  1484.    /* this is misnamed, it actually refers to whether rtasm is enabled or not */
  1485.    if (!rtasm_cpu_has_sse())
  1486.       goto fail;
  1487.  
  1488.    p = os_malloc_aligned(sizeof(struct translate_sse), 16);
  1489.    if (p == NULL)
  1490.       goto fail;
  1491.  
  1492.    memset(p, 0, sizeof(*p));
  1493.    memcpy(p->consts, consts, sizeof(consts));
  1494.  
  1495.    p->translate.key = *key;
  1496.    p->translate.release = translate_sse_release;
  1497.    p->translate.set_buffer = translate_sse_set_buffer;
  1498.  
  1499.    assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS);
  1500.  
  1501.    for (i = 0; i < key->nr_elements; i++) {
  1502.       if (key->element[i].type == TRANSLATE_ELEMENT_NORMAL) {
  1503.          unsigned j;
  1504.  
  1505.          p->nr_buffers =
  1506.             MAX2(p->nr_buffers, key->element[i].input_buffer + 1);
  1507.  
  1508.          if (key->element[i].instance_divisor) {
  1509.             p->use_instancing = TRUE;
  1510.          }
  1511.  
  1512.          /*
  1513.           * Map vertex element to vertex buffer variant.
  1514.           */
  1515.          for (j = 0; j < p->nr_buffer_variants; j++) {
  1516.             if (p->buffer_variant[j].buffer_index ==
  1517.                 key->element[i].input_buffer
  1518.                 && p->buffer_variant[j].instance_divisor ==
  1519.                 key->element[i].instance_divisor) {
  1520.                break;
  1521.             }
  1522.          }
  1523.          if (j == p->nr_buffer_variants) {
  1524.             p->buffer_variant[j].buffer_index = key->element[i].input_buffer;
  1525.             p->buffer_variant[j].instance_divisor =
  1526.                key->element[i].instance_divisor;
  1527.             p->nr_buffer_variants++;
  1528.          }
  1529.          p->element_to_buffer_variant[i] = j;
  1530.       }
  1531.       else {
  1532.          assert(key->element[i].type == TRANSLATE_ELEMENT_INSTANCE_ID);
  1533.  
  1534.          p->element_to_buffer_variant[i] = ELEMENT_BUFFER_INSTANCE_ID;
  1535.       }
  1536.    }
  1537.  
  1538.    if (0)
  1539.       debug_printf("nr_buffers: %d\n", p->nr_buffers);
  1540.  
  1541.    if (!build_vertex_emit(p, &p->linear_func, 0))
  1542.       goto fail;
  1543.  
  1544.    if (!build_vertex_emit(p, &p->elt_func, 4))
  1545.       goto fail;
  1546.  
  1547.    if (!build_vertex_emit(p, &p->elt16_func, 2))
  1548.       goto fail;
  1549.  
  1550.    if (!build_vertex_emit(p, &p->elt8_func, 1))
  1551.       goto fail;
  1552.  
  1553.    p->translate.run = (run_func) x86_get_func(&p->linear_func);
  1554.    if (p->translate.run == NULL)
  1555.       goto fail;
  1556.  
  1557.    p->translate.run_elts = (run_elts_func) x86_get_func(&p->elt_func);
  1558.    if (p->translate.run_elts == NULL)
  1559.       goto fail;
  1560.  
  1561.    p->translate.run_elts16 = (run_elts16_func) x86_get_func(&p->elt16_func);
  1562.    if (p->translate.run_elts16 == NULL)
  1563.       goto fail;
  1564.  
  1565.    p->translate.run_elts8 = (run_elts8_func) x86_get_func(&p->elt8_func);
  1566.    if (p->translate.run_elts8 == NULL)
  1567.       goto fail;
  1568.  
  1569.    return &p->translate;
  1570.  
  1571.  fail:
  1572.    if (p)
  1573.       translate_sse_release(&p->translate);
  1574.  
  1575.    return NULL;
  1576. }
  1577.  
  1578.  
  1579. #else
  1580.  
  1581. struct translate *
  1582. translate_sse2_create(const struct translate_key *key)
  1583. {
  1584.    return NULL;
  1585. }
  1586.  
  1587. #endif
  1588.