mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	Extend what's currently done for shift because the HW performs this masking implicitly: (rotl:i32 x, (and y, 31)) -> (rotl:i32 x, y) I use the newly factored out multiclass that was only supporting shifts so far. For testing I extended my testcase for the new rotation idiom. <rdar://problem/15295856> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203718 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			135 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=generic | FileCheck %s
 | 
						|
 | 
						|
; Check that we recognize this idiom for rotation too:
 | 
						|
;    a << (b & (OpSize-1)) | a >> ((0 - b) & (OpSize-1))
 | 
						|
 | 
						|
define i32 @rotate_left_32(i32 %a, i32 %b) {
 | 
						|
; CHECK-LABEL: rotate_left_32:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: roll
 | 
						|
entry:
 | 
						|
  %and = and i32 %b, 31
 | 
						|
  %shl = shl i32 %a, %and
 | 
						|
  %0 = sub i32 0, %b
 | 
						|
  %and3 = and i32 %0, 31
 | 
						|
  %shr = lshr i32 %a, %and3
 | 
						|
  %or = or i32 %shl, %shr
 | 
						|
  ret i32 %or
 | 
						|
}
 | 
						|
 | 
						|
define i32 @rotate_right_32(i32 %a, i32 %b) {
 | 
						|
; CHECK-LABEL: rotate_right_32:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rorl
 | 
						|
entry:
 | 
						|
  %and = and i32 %b, 31
 | 
						|
  %shl = lshr i32 %a, %and
 | 
						|
  %0 = sub i32 0, %b
 | 
						|
  %and3 = and i32 %0, 31
 | 
						|
  %shr = shl i32 %a, %and3
 | 
						|
  %or = or i32 %shl, %shr
 | 
						|
  ret i32 %or
 | 
						|
}
 | 
						|
 | 
						|
define i64 @rotate_left_64(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: rotate_left_64:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rolq
 | 
						|
entry:
 | 
						|
  %and = and i64 %b, 63
 | 
						|
  %shl = shl i64 %a, %and
 | 
						|
  %0 = sub i64 0, %b
 | 
						|
  %and3 = and i64 %0, 63
 | 
						|
  %shr = lshr i64 %a, %and3
 | 
						|
  %or = or i64 %shl, %shr
 | 
						|
  ret i64 %or
 | 
						|
}
 | 
						|
 | 
						|
define i64 @rotate_right_64(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: rotate_right_64:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rorq
 | 
						|
entry:
 | 
						|
  %and = and i64 %b, 63
 | 
						|
  %shl = lshr i64 %a, %and
 | 
						|
  %0 = sub i64 0, %b
 | 
						|
  %and3 = and i64 %0, 63
 | 
						|
  %shr = shl i64 %a, %and3
 | 
						|
  %or = or i64 %shl, %shr
 | 
						|
  ret i64 %or
 | 
						|
}
 | 
						|
 | 
						|
; Also check mem operand.
 | 
						|
 | 
						|
define void @rotate_left_m32(i32 *%pa, i32 %b) {
 | 
						|
; CHECK-LABEL: rotate_left_m32:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: roll
 | 
						|
; no store:
 | 
						|
; CHECK-NOT: mov
 | 
						|
entry:
 | 
						|
  %a = load i32* %pa, align 16
 | 
						|
  %and = and i32 %b, 31
 | 
						|
  %shl = shl i32 %a, %and
 | 
						|
  %0 = sub i32 0, %b
 | 
						|
  %and3 = and i32 %0, 31
 | 
						|
  %shr = lshr i32 %a, %and3
 | 
						|
  %or = or i32 %shl, %shr
 | 
						|
  store i32 %or, i32* %pa, align 32
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @rotate_right_m32(i32 *%pa, i32 %b) {
 | 
						|
; CHECK-LABEL: rotate_right_m32:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rorl
 | 
						|
; no store:
 | 
						|
; CHECK-NOT: mov
 | 
						|
entry:
 | 
						|
  %a = load i32* %pa, align 16
 | 
						|
  %and = and i32 %b, 31
 | 
						|
  %shl = lshr i32 %a, %and
 | 
						|
  %0 = sub i32 0, %b
 | 
						|
  %and3 = and i32 %0, 31
 | 
						|
  %shr = shl i32 %a, %and3
 | 
						|
  %or = or i32 %shl, %shr
 | 
						|
  store i32 %or, i32* %pa, align 32
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @rotate_left_m64(i64 *%pa, i64 %b) {
 | 
						|
; CHECK-LABEL: rotate_left_m64:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rolq
 | 
						|
; no store:
 | 
						|
; CHECK-NOT: mov
 | 
						|
entry:
 | 
						|
  %a = load i64* %pa, align 16
 | 
						|
  %and = and i64 %b, 63
 | 
						|
  %shl = shl i64 %a, %and
 | 
						|
  %0 = sub i64 0, %b
 | 
						|
  %and3 = and i64 %0, 63
 | 
						|
  %shr = lshr i64 %a, %and3
 | 
						|
  %or = or i64 %shl, %shr
 | 
						|
  store i64 %or, i64* %pa, align 64
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @rotate_right_m64(i64 *%pa, i64 %b) {
 | 
						|
; CHECK-LABEL: rotate_right_m64:
 | 
						|
; CHECK-NOT: and
 | 
						|
; CHECK: rorq
 | 
						|
; no store:
 | 
						|
; CHECK-NOT: mov
 | 
						|
entry:
 | 
						|
  %a = load i64* %pa, align 16
 | 
						|
  %and = and i64 %b, 63
 | 
						|
  %shl = lshr i64 %a, %and
 | 
						|
  %0 = sub i64 0, %b
 | 
						|
  %and3 = and i64 %0, 63
 | 
						|
  %shr = shl i64 %a, %and3
 | 
						|
  %or = or i64 %shl, %shr
 | 
						|
  store i64 %or, i64* %pa, align 64
 | 
						|
  ret void
 | 
						|
}
 |