+ for (i = 0; i < output_desc->nr_channels; ++i) {
+ switch (output_desc->channel[0].size) {
+ case 8:
+ if (swizzle[i] >= PIPE_SWIZZLE_0) {
+ unsigned v = 0;
+ if (swizzle[i] == PIPE_SWIZZLE_1) {
+ switch (output_desc->channel[0].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ v = output_desc->channel[0].normalized ? 0xff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_SIGNED:
+ v = output_desc->channel[0].normalized ? 0x7f : 1;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ x86_mov8_imm(p->func, x86_make_disp(dst, i * 1), v);
+ }
+ else {
+ x86_mov8(p->func, tmp, x86_make_disp(src, swizzle[i] * 1));
+ x86_mov8(p->func, x86_make_disp(dst, i * 1), tmp);
+ }
+ break;
+ case 16:
+ if (swizzle[i] >= PIPE_SWIZZLE_0) {
+ unsigned v = 0;
+ if (swizzle[i] == PIPE_SWIZZLE_1) {
+ switch (output_desc->channel[1].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ v = output_desc->channel[1].normalized ? 0xffff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_SIGNED:
+ v = output_desc->channel[1].normalized ? 0x7fff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_FLOAT:
+ v = 0x3c00;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ x86_mov16_imm(p->func, x86_make_disp(dst, i * 2), v);
+ }
+ else if (swizzle[i] == PIPE_SWIZZLE_0) {
+ x86_mov16_imm(p->func, x86_make_disp(dst, i * 2), 0);
+ }
+ else {
+ x86_mov16(p->func, tmp, x86_make_disp(src, swizzle[i] * 2));
+ x86_mov16(p->func, x86_make_disp(dst, i * 2), tmp);
+ }
+ break;
+ case 32:
+ if (swizzle[i] >= PIPE_SWIZZLE_0) {
+ unsigned v = 0;
+ if (swizzle[i] == PIPE_SWIZZLE_1) {
+ switch (output_desc->channel[1].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ v = output_desc->channel[1].normalized ? 0xffffffff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_SIGNED:
+ v = output_desc->channel[1].normalized ? 0x7fffffff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_FLOAT:
+ v = 0x3f800000;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ x86_mov_imm(p->func, x86_make_disp(dst, i * 4), v);
+ }
+ else {
+ x86_mov(p->func, tmp, x86_make_disp(src, swizzle[i] * 4));
+ x86_mov(p->func, x86_make_disp(dst, i * 4), tmp);
+ }
+ break;
+ case 64:
+ if (swizzle[i] >= PIPE_SWIZZLE_0) {
+ unsigned l = 0;
+ unsigned h = 0;
+ if (swizzle[i] == PIPE_SWIZZLE_1) {
+ switch (output_desc->channel[1].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ h = output_desc->channel[1].normalized ? 0xffffffff : 0;
+ l = output_desc->channel[1].normalized ? 0xffffffff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_SIGNED:
+ h = output_desc->channel[1].normalized ? 0x7fffffff : 0;
+ l = output_desc->channel[1].normalized ? 0xffffffff : 1;
+ break;
+ case UTIL_FORMAT_TYPE_FLOAT:
+ h = 0x3ff00000;
+ l = 0;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ x86_mov_imm(p->func, x86_make_disp(dst, i * 8), l);
+ x86_mov_imm(p->func, x86_make_disp(dst, i * 8 + 4), h);
+ }
+ else {
+ if (x86_target_caps(p->func) & X86_SSE) {
+ struct x86_reg tmpXMM = x86_make_reg(file_XMM, 0);
+ emit_load64(p, tmp, tmpXMM,
+ x86_make_disp(src, swizzle[i] * 8));
+ emit_store64(p, x86_make_disp(dst, i * 8), tmp, tmpXMM);
+ }
+ else {
+ x86_mov(p->func, tmp, x86_make_disp(src, swizzle[i] * 8));
+ x86_mov(p->func, x86_make_disp(dst, i * 8), tmp);
+ x86_mov(p->func, tmp,
+ x86_make_disp(src, swizzle[i] * 8 + 4));
+ x86_mov(p->func, x86_make_disp(dst, i * 8 + 4), tmp);
+ }
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ /* special case for draw's EMIT_4UB (RGBA) and EMIT_4UB_BGRA */
+ else if ((x86_target_caps(p->func) & X86_SSE2) &&
+ a->input_format == PIPE_FORMAT_R32G32B32A32_FLOAT &&
+ (0 || a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM
+ || a-> output_format == PIPE_FORMAT_R8G8B8A8_UNORM)) {
+ struct x86_reg dataXMM = x86_make_reg(file_XMM, 0);
+
+ /* load */
+ sse_movups(p->func, dataXMM, src);
+
+ if (a->output_format == PIPE_FORMAT_B8G8R8A8_UNORM) {
+ sse_shufps(p->func, dataXMM, dataXMM, SHUF(2, 1, 0, 3));
+ }