diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 19a0f7262ff6e..118eeeeec1f2c 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1380,11 +1380,16 @@ fn trans_eager_binop(bcx: block, let rhs = rhs_datum.to_appropriate_llval(bcx); let rhs_t = rhs_datum.ty; - let intype = { + let mut intype = { if ty::type_is_bot(lhs_t) { rhs_t } else { lhs_t } }; + let tcx = bcx.tcx(); + if ty::type_is_simd(tcx, intype) { + intype = ty::simd_type(tcx, intype); + } let is_float = ty::type_is_fp(intype); + let signed = ty::type_is_signed(intype); let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs); @@ -1409,7 +1414,7 @@ fn trans_eager_binop(bcx: block, // Only zero-check integers; fp /0 is NaN bcx = base::fail_if_zero(bcx, binop_expr.span, op, rhs, rhs_t); - if ty::type_is_signed(intype) { + if signed { SDiv(bcx, lhs, rhs) } else { UDiv(bcx, lhs, rhs) @@ -1423,7 +1428,7 @@ fn trans_eager_binop(bcx: block, // Only zero-check integers; fp %0 is NaN bcx = base::fail_if_zero(bcx, binop_expr.span, op, rhs, rhs_t); - if ty::type_is_signed(intype) { + if signed { SRem(bcx, lhs, rhs) } else { URem(bcx, lhs, rhs) @@ -1435,7 +1440,7 @@ fn trans_eager_binop(bcx: block, ast::bitxor => Xor(bcx, lhs, rhs), ast::shl => Shl(bcx, lhs, rhs), ast::shr => { - if ty::type_is_signed(intype) { + if signed { AShr(bcx, lhs, rhs) } else { LShr(bcx, lhs, rhs) } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index dce899010c76d..5a02449cee91e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1661,7 +1661,8 @@ fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool { pub fn type_is_immediate(cx: ctxt, ty: t) -> bool { return type_is_scalar(ty) || type_is_boxed(ty) || type_is_unique(ty) || type_is_region_ptr(ty) || - type_is_newtype_immediate(cx, ty); + type_is_newtype_immediate(cx, ty) || + type_is_simd(cx, ty); } pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { @@ -4074,7 +4075,7 @@ pub fn struct_fields(cx: ctxt, did: ast::def_id, substs: &substs) } } -pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { +pub fn is_binopable(cx: ctxt, ty: t, op: ast::binop) -> bool { static tycat_other: int = 0; static tycat_bool: int = 1; static tycat_int: int = 2; @@ -4114,7 +4115,10 @@ pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { } } - fn tycat(ty: t) -> int { + fn tycat(cx: ctxt, ty: t) -> int { + if type_is_simd(cx, ty) { + return tycat(cx, simd_type(cx, ty)) + } match get(ty).sty { ty_bool => tycat_bool, ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int, @@ -4139,7 +4143,7 @@ pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { /*bot*/ ~[f, f, f, f, f, f, f, f], /*struct*/ ~[t, t, t, t, f, f, t, t]]; - return tbl[tycat(ty)][opcat(op)]; + return tbl[tycat(cx, ty)][opcat(op)]; } pub fn ty_params_to_tys(tcx: ty::ctxt, generics: &ast::Generics) -> ~[t] { diff --git a/src/test/run-pass/simd-binop.rs b/src/test/run-pass/simd-binop.rs new file mode 100644 index 0000000000000..1e6c8b07fa0ee --- /dev/null +++ b/src/test/run-pass/simd-binop.rs @@ -0,0 +1,28 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::unstable::simd::{i32x4, f32x4}; + +fn test_int(e: i32) -> i32 { + let v = i32x4(e, 0i32, 0i32, 0i32); + let i32x4(e2, _, _, _) = v * v + v - v; + e2 +} + +fn test_float(e: f32) -> f32 { + let v = f32x4(e, 0f32, 0f32, 0f32); + let f32x4(e2, _, _, _) = v * v + v - v; + e2 +} + +fn main() { + assert_eq!(test_int(3i32), 9i32); + assert_eq!(test_float(3f32), 9f32); +}