@@ -1492,26 +1492,26 @@ tag scalar_type { nil_type; signed_int; unsigned_int; floating_point; }
1492
1492
1493
1493
1494
1494
fn compare_scalar_types ( cx : @block_ctxt , lhs : ValueRef , rhs : ValueRef ,
1495
- t : ty:: t , llop : ValueRef ) -> result {
1496
- let f = bind compare_scalar_values ( cx, lhs, rhs, _, llop ) ;
1495
+ t : ty:: t , op : ast :: binop ) -> result {
1496
+ let f = bind compare_scalar_values ( cx, lhs, rhs, _, op ) ;
1497
1497
1498
1498
alt ty:: struct ( bcx_tcx ( cx) , t) {
1499
- ty:: ty_nil. { ret f ( nil_type) ; }
1499
+ ty:: ty_nil. { ret rslt ( cx , f ( nil_type) ) ; }
1500
1500
ty:: ty_bool. | ty:: ty_uint. | ty:: ty_ptr ( _) | ty:: ty_char. {
1501
- ret f ( unsigned_int) ;
1501
+ ret rslt ( cx , f ( unsigned_int) ) ;
1502
1502
}
1503
- ty:: ty_int. { ret f ( signed_int) ; }
1504
- ty:: ty_float. { ret f( floating_point) ; }
1503
+ ty:: ty_int. { ret rslt ( cx , f ( signed_int) ) ; }
1504
+ ty:: ty_float. { ret rslt ( cx , f ( floating_point) ) ; }
1505
1505
ty:: ty_machine ( _) {
1506
1506
if ty:: type_is_fp ( bcx_tcx ( cx) , t) {
1507
1507
// Floating point machine types
1508
- ret f( floating_point) ;
1508
+ ret rslt ( cx , f ( floating_point) ) ;
1509
1509
} else if ty:: type_is_signed ( bcx_tcx ( cx) , t) {
1510
1510
// Signed, integral machine types
1511
- ret f( signed_int) ;
1511
+ ret rslt ( cx , f ( signed_int) ) ;
1512
1512
} else {
1513
1513
// Unsigned, integral machine types
1514
- ret f( unsigned_int) ;
1514
+ ret rslt ( cx , f ( unsigned_int) ) ;
1515
1515
}
1516
1516
}
1517
1517
ty:: ty_type. {
@@ -1535,34 +1535,47 @@ fn compare_scalar_types(cx: @block_ctxt, lhs: ValueRef, rhs: ValueRef,
1535
1535
1536
1536
// A helper function to do the actual comparison of scalar values.
1537
1537
fn compare_scalar_values( cx : @block_ctxt , lhs : ValueRef , rhs : ValueRef ,
1538
- nt : scalar_type , llop : ValueRef ) -> result {
1539
- let eq_cmp;
1540
- let lt_cmp;
1541
- let le_cmp;
1542
- alt nt {
1538
+ nt : scalar_type , op : ast:: binop ) -> ValueRef {
1539
+ let cmp = alt nt {
1543
1540
nil_type. {
1544
1541
// We don't need to do actual comparisons for nil.
1545
1542
// () == () holds but () < () does not.
1546
- eq_cmp = 1 u;
1547
- lt_cmp = 0 u;
1548
- le_cmp = 1 u;
1543
+ alt op {
1544
+ ast : : eq. | ast:: le. | ast:: ge. { 1 u }
1545
+ ast:: ne. | ast:: lt. | ast:: gt. { 0 u }
1546
+ }
1549
1547
}
1550
1548
floating_point. {
1551
- eq_cmp = lib:: llvm:: LLVMRealUEQ ;
1552
- lt_cmp = lib:: llvm:: LLVMRealULT ;
1553
- le_cmp = lib:: llvm:: LLVMRealULE ;
1549
+ alt op {
1550
+ ast:: eq. { lib:: llvm:: LLVMRealOEQ }
1551
+ ast:: ne. { lib:: llvm:: LLVMRealUNE }
1552
+ ast:: lt. { lib:: llvm:: LLVMRealOLT }
1553
+ ast:: le. { lib:: llvm:: LLVMRealOLE }
1554
+ ast:: gt. { lib:: llvm:: LLVMRealOGT }
1555
+ ast:: ge. { lib:: llvm:: LLVMRealOGE }
1556
+ }
1554
1557
}
1555
1558
signed_int. {
1556
- eq_cmp = lib:: llvm:: LLVMIntEQ ;
1557
- lt_cmp = lib:: llvm:: LLVMIntSLT ;
1558
- le_cmp = lib:: llvm:: LLVMIntSLE ;
1559
+ alt op {
1560
+ ast:: eq. { lib:: llvm:: LLVMIntEQ }
1561
+ ast:: ne. { lib:: llvm:: LLVMIntNE }
1562
+ ast:: lt. { lib:: llvm:: LLVMIntSLT }
1563
+ ast:: le. { lib:: llvm:: LLVMIntSLE }
1564
+ ast:: gt. { lib:: llvm:: LLVMIntSGT }
1565
+ ast:: ge. { lib:: llvm:: LLVMIntSGE }
1566
+ }
1559
1567
}
1560
1568
unsigned_int. {
1561
- eq_cmp = lib:: llvm:: LLVMIntEQ ;
1562
- lt_cmp = lib:: llvm:: LLVMIntULT ;
1563
- le_cmp = lib:: llvm:: LLVMIntULE ;
1569
+ alt op {
1570
+ ast:: eq. { lib:: llvm:: LLVMIntEQ }
1571
+ ast:: ne. { lib:: llvm:: LLVMIntNE }
1572
+ ast:: lt. { lib:: llvm:: LLVMIntULT }
1573
+ ast:: le. { lib:: llvm:: LLVMIntULE }
1574
+ ast:: gt. { lib:: llvm:: LLVMIntUGT }
1575
+ ast:: ge. { lib:: llvm:: LLVMIntUGE }
1576
+ }
1564
1577
}
1565
- }
1578
+ } ;
1566
1579
// FIXME: This wouldn't be necessary if we could bind methods off of
1567
1580
// objects and therefore abstract over FCmp and ICmp (issue #435). Then
1568
1581
// we could just write, e.g., "cmp_fn = bind FCmp(cx, _, _, _);" in
@@ -1579,26 +1592,7 @@ fn compare_scalar_values(cx: @block_ctxt, lhs: ValueRef, rhs: ValueRef,
1579
1592
} else { r = ICmp ( cx, op, lhs, rhs) ; }
1580
1593
ret r;
1581
1594
}
1582
- let last_cx = new_sub_block_ctxt ( cx, "last" ) ;
1583
- let eq_cx = new_sub_block_ctxt ( cx, "eq" ) ;
1584
- let eq_result = generic_cmp ( eq_cx, nt, eq_cmp, lhs, rhs) ;
1585
- Br ( eq_cx, last_cx. llbb ) ;
1586
- let lt_cx = new_sub_block_ctxt ( cx, "lt" ) ;
1587
- let lt_result = generic_cmp ( lt_cx, nt, lt_cmp, lhs, rhs) ;
1588
- Br ( lt_cx, last_cx. llbb ) ;
1589
- let le_cx = new_sub_block_ctxt ( cx, "le" ) ;
1590
- let le_result = generic_cmp ( le_cx, nt, le_cmp, lhs, rhs) ;
1591
- Br ( le_cx, last_cx. llbb ) ;
1592
- let unreach_cx = new_sub_block_ctxt ( cx, "unreach" ) ;
1593
- Unreachable ( unreach_cx) ;
1594
- let llswitch = Switch ( cx, llop, unreach_cx. llbb , 3 u) ;
1595
- AddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_eq) , eq_cx. llbb ) ;
1596
- AddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_lt) , lt_cx. llbb ) ;
1597
- AddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_le) , le_cx. llbb ) ;
1598
- let last_result =
1599
- Phi ( last_cx, T_i1 ( ) , [ eq_result, lt_result, le_result] ,
1600
- [ eq_cx. llbb , lt_cx. llbb , le_cx. llbb ] ) ;
1601
- ret rslt( last_cx, last_result) ;
1595
+ ret generic_cmp( cx, nt, cmp, lhs, rhs) ;
1602
1596
}
1603
1597
1604
1598
type val_pair_fn = fn ( @block_ctxt, ValueRef , ValueRef ) -> @block_ctxt;
@@ -1912,16 +1906,6 @@ fn call_cmp_glue(cx: @block_ctxt, lhs: ValueRef, rhs: ValueRef, t: ty::t,
1912
1906
ret rslt( bcx, Load ( bcx, llcmpresultptr) ) ;
1913
1907
}
1914
1908
1915
- // Compares two values. Performs the simple scalar comparison if the types are
1916
- // scalar and calls to comparison glue otherwise.
1917
- fn compare ( cx : @block_ctxt , lhs : ValueRef , rhs : ValueRef , t : ty:: t ,
1918
- llop : ValueRef ) -> result {
1919
- if ty:: type_is_scalar ( bcx_tcx ( cx) , t) {
1920
- ret compare_scalar_types ( cx, lhs, rhs, t, llop) ;
1921
- }
1922
- ret call_cmp_glue ( cx, lhs, rhs, t, llop) ;
1923
- }
1924
-
1925
1909
fn take_ty( cx: @block_ctxt, v: ValueRef , t: ty:: t) -> @block_ctxt {
1926
1910
if ty:: type_has_pointers( bcx_tcx( cx) , t) {
1927
1911
ret call_tydesc_glue( cx, v, t, abi:: tydesc_field_take_glue) ;
@@ -2262,6 +2246,11 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
2262
2246
2263
2247
fn trans_compare( cx: @block_ctxt, op: ast:: binop, lhs: ValueRef ,
2264
2248
_lhs_t: ty:: t, rhs: ValueRef , rhs_t: ty:: t) -> result {
2249
+ if ty:: type_is_scalar( bcx_tcx( cx) , rhs_t) {
2250
+ let rs = compare_scalar_types( cx, lhs, rhs, rhs_t, op) ;
2251
+ ret rslt( rs. bcx, rs. val) ;
2252
+ }
2253
+
2265
2254
// Determine the operation we need.
2266
2255
let llop;
2267
2256
alt op {
@@ -2270,7 +2259,7 @@ fn trans_compare(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
2270
2259
ast:: le. | ast:: gt. { llop = C_u8 ( abi:: cmp_glue_op_le) ; }
2271
2260
}
2272
2261
2273
- let rs = compare ( cx, lhs, rhs, rhs_t, llop) ;
2262
+ let rs = call_cmp_glue ( cx, lhs, rhs, rhs_t, llop) ;
2274
2263
2275
2264
// Invert the result if necessary.
2276
2265
alt op {
0 commit comments