Sub with borrow
(&mut self, left: JitTemp, right: JitTemp, borrow: JitTemp)
| 264 | |
| 265 | /// Sub with borrow |
| 266 | pub fn sbb<const FLAG:bool>(&mut self, left: JitTemp, right: JitTemp, borrow: JitTemp) -> JitTemp { |
| 267 | use JitTemp::*; |
| 268 | use Flags::*; |
| 269 | let flags = vec![OF, SF, ZF, AF, PF, CF]; |
| 270 | match (left.clone(), right.clone(), borrow.clone()) { |
| 271 | (Value(val_left, typ_left), Value(val_right, _), Flag(val_borrow)) => { |
| 272 | let (res, flag) = self.builder.ins().isub_borrow(val_left, val_right, val_borrow); |
| 273 | self.context.set_flags(flags, (val_left, val_right, flag)); |
| 274 | Value(res, typ_left) |
| 275 | }, |
| 276 | (_, _, borrow) if borrow.is_const() => { |
| 277 | // see note in self.adc |
| 278 | let borrow = borrow.into_usize(self.builder).unwrap(); |
| 279 | if borrow == 0 { |
| 280 | return self.sub::<FLAG>(left, right); |
| 281 | } else { |
| 282 | unimplemented!() |
| 283 | } |
| 284 | }, |
| 285 | (left @ Value(_, _), right @ _, borrow @ _) | |
| 286 | (left @ _, right @ Value(_, _), borrow @ _) | |
| 287 | (left @ _, right @ _, borrow @ Flag(_)) => { |
| 288 | let typ = Type::int((left.width() * 8) as u16).unwrap(); |
| 289 | let _left = left.into_ssa(typ, self.builder); |
| 290 | let _right = right.zero_extend(self.builder, left.width()).into_ssa(typ, self.builder); |
| 291 | let mut _borrow = borrow.into_ssa(types::IFLAGS, self.builder); |
| 292 | let (res, flag) = self.builder.ins().isub_borrow(_left, _right, _borrow); |
| 293 | self.context.set_flags(flags, (_left, _right, flag)); |
| 294 | Value(res, typ) |
| 295 | }, |
| 296 | (Ref(base, offset), off, borrow) if off.is_const() && borrow.is_const() => { |
| 297 | let off = off.into_usize(self.builder).unwrap(); |
| 298 | let borrow = borrow.into_usize(self.builder).unwrap(); |
| 299 | assert_eq!(HOST_WIDTH, 8); |
| 300 | if borrow == 0 { |
| 301 | Ref(base, do_op!(self.context, FLAG, offset, off, "sub {}, {}", flags, +)) |
| 302 | } else { |
| 303 | Ref(base, do_op!(self.context, FLAG, offset, off, "stc; sbb {}, {}", flags, +)) |
| 304 | } |
| 305 | }, |
| 306 | (offset, Ref(base, off), borrow) if offset.is_const() && borrow.is_const() => { |
| 307 | let offset = offset.into_usize(self.builder).unwrap(); |
| 308 | let borrow = borrow.into_usize(self.builder).unwrap(); |
| 309 | assert_eq!(HOST_WIDTH, 8); |
| 310 | if borrow == 0 { |
| 311 | Ref(base, do_op!(self.context, FLAG, offset, off, "sub {}, {}", flags, +)) |
| 312 | } else { |
| 313 | Ref(base, do_op!(self.context, FLAG, offset, off, "stc; sbb {}, {}", flags, +)) |
| 314 | } |
| 315 | }, |
| 316 | (left_c, mut right_c, mut borrow) |
| 317 | if left_c.clone().is_const() |
| 318 | && right_c.clone().is_const() |
| 319 | && borrow.clone().is_const() => { |
| 320 | right_c = right_c.zero_extend(self.builder, left_c.clone().width()); |
| 321 | let borrow = borrow.into_usize(self.builder).unwrap(); |
| 322 | assert_eq!(HOST_WIDTH, 8); |
| 323 | if borrow == 0 { |