|
3 | 3 | // Some variants are never constructed, but we still want them as options in the future. |
4 | 4 | #![allow(dead_code)] |
5 | 5 |
|
6 | | -use crate::binemit::CodeOffset; |
7 | 6 | use crate::ir::Type; |
8 | 7 | use crate::isa::aarch64::inst::*; |
9 | 8 | use crate::isa::aarch64::lower::ty_bits; |
| 9 | +use crate::machinst::MachLabel; |
10 | 10 |
|
11 | 11 | use regalloc::{RealRegUniverse, Reg, Writable}; |
12 | 12 |
|
13 | | -use core::convert::{Into, TryFrom}; |
| 13 | +use core::convert::Into; |
14 | 14 | use std::string::String; |
15 | 15 |
|
16 | 16 | /// A shift operator for a register or immediate. |
@@ -303,78 +303,44 @@ impl CondBrKind { |
303 | 303 |
|
304 | 304 | /// A branch target. Either unresolved (basic-block index) or resolved (offset |
305 | 305 | /// from end of current instruction). |
306 | | -#[derive(Clone, Copy, Debug)] |
| 306 | +#[derive(Clone, Copy, Debug, PartialEq, Eq)] |
307 | 307 | pub enum BranchTarget { |
308 | | - /// An unresolved reference to a BlockIndex, as passed into |
| 308 | + /// An unresolved reference to a Label, as passed into |
309 | 309 | /// `lower_branch_group()`. |
310 | | - Block(BlockIndex), |
311 | | - /// A resolved reference to another instruction, after |
312 | | - /// `Inst::with_block_offsets()`. |
| 310 | + Label(MachLabel), |
| 311 | + /// A fixed PC offset. |
313 | 312 | ResolvedOffset(isize), |
314 | 313 | } |
315 | 314 |
|
316 | 315 | impl BranchTarget { |
317 | | - /// Lower the branch target given offsets of each block. |
318 | | - pub fn lower(&mut self, targets: &[CodeOffset], my_offset: CodeOffset) { |
319 | | - match self { |
320 | | - &mut BranchTarget::Block(bix) => { |
321 | | - let bix = usize::try_from(bix).unwrap(); |
322 | | - assert!(bix < targets.len()); |
323 | | - let block_offset_in_func = targets[bix]; |
324 | | - let branch_offset = (block_offset_in_func as isize) - (my_offset as isize); |
325 | | - *self = BranchTarget::ResolvedOffset(branch_offset); |
326 | | - } |
327 | | - &mut BranchTarget::ResolvedOffset(..) => {} |
328 | | - } |
329 | | - } |
330 | | - |
331 | | - /// Get the block index. |
332 | | - pub fn as_block_index(&self) -> Option<BlockIndex> { |
| 316 | + /// Return the target's label, if it is a label-based target. |
| 317 | + pub fn as_label(self) -> Option<MachLabel> { |
333 | 318 | match self { |
334 | | - &BranchTarget::Block(bix) => Some(bix), |
| 319 | + BranchTarget::Label(l) => Some(l), |
335 | 320 | _ => None, |
336 | 321 | } |
337 | 322 | } |
338 | 323 |
|
339 | | - /// Get the offset as 4-byte words. Returns `0` if not |
340 | | - /// yet resolved (in that case, we're only computing |
341 | | - /// size and the offset doesn't matter). |
342 | | - pub fn as_offset_words(&self) -> isize { |
343 | | - match self { |
344 | | - &BranchTarget::ResolvedOffset(off) => off >> 2, |
| 324 | + /// Return the target's offset, if specified, or zero if label-based. |
| 325 | + pub fn as_offset19_or_zero(self) -> u32 { |
| 326 | + let off = match self { |
| 327 | + BranchTarget::ResolvedOffset(off) => off >> 2, |
345 | 328 | _ => 0, |
346 | | - } |
| 329 | + }; |
| 330 | + assert!(off <= 0x3ffff); |
| 331 | + assert!(off >= -0x40000); |
| 332 | + (off as u32) & 0x7ffff |
347 | 333 | } |
348 | 334 |
|
349 | | - /// Get the offset as a 26-bit offset suitable for a 26-bit jump, or `None` if overflow. |
350 | | - pub fn as_off26(&self) -> Option<u32> { |
351 | | - let off = self.as_offset_words(); |
352 | | - if (off < (1 << 25)) && (off >= -(1 << 25)) { |
353 | | - Some((off as u32) & ((1 << 26) - 1)) |
354 | | - } else { |
355 | | - None |
356 | | - } |
357 | | - } |
358 | | - |
359 | | - /// Get the offset as a 19-bit offset, or `None` if overflow. |
360 | | - pub fn as_off19(&self) -> Option<u32> { |
361 | | - let off = self.as_offset_words(); |
362 | | - if (off < (1 << 18)) && (off >= -(1 << 18)) { |
363 | | - Some((off as u32) & ((1 << 19) - 1)) |
364 | | - } else { |
365 | | - None |
366 | | - } |
367 | | - } |
368 | | - |
369 | | - /// Map the block index given a transform map. |
370 | | - pub fn map(&mut self, block_index_map: &[BlockIndex]) { |
371 | | - match self { |
372 | | - &mut BranchTarget::Block(ref mut bix) => { |
373 | | - let n = block_index_map[usize::try_from(*bix).unwrap()]; |
374 | | - *bix = n; |
375 | | - } |
376 | | - &mut BranchTarget::ResolvedOffset(_) => {} |
377 | | - } |
| 335 | + /// Return the target's offset, if specified, or zero if label-based. |
| 336 | + pub fn as_offset26_or_zero(self) -> u32 { |
| 337 | + let off = match self { |
| 338 | + BranchTarget::ResolvedOffset(off) => off >> 2, |
| 339 | + _ => 0, |
| 340 | + }; |
| 341 | + assert!(off <= 0x1ffffff); |
| 342 | + assert!(off >= -0x2000000); |
| 343 | + (off as u32) & 0x3ffffff |
378 | 344 | } |
379 | 345 | } |
380 | 346 |
|
@@ -507,7 +473,7 @@ impl ShowWithRRU for Cond { |
507 | 473 | impl ShowWithRRU for BranchTarget { |
508 | 474 | fn show_rru(&self, _mb_rru: Option<&RealRegUniverse>) -> String { |
509 | 475 | match self { |
510 | | - &BranchTarget::Block(block) => format!("block{}", block), |
| 476 | + &BranchTarget::Label(label) => format!("label{:?}", label.get()), |
511 | 477 | &BranchTarget::ResolvedOffset(off) => format!("{}", off), |
512 | 478 | } |
513 | 479 | } |
|
0 commit comments