blob: fd3757303bc18e212677ee5b6522e49daa24419a [file] [log] [blame]
Lauro Ramos Venancioa38bbf72007-01-12 20:35:49 +00001//===-- ARMCommon.cpp - Define support functions for ARM --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the "Instituto Nokia de Tecnologia" and
6// is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10//
11//
12//
13//===----------------------------------------------------------------------===//
14#include "ARMCommon.h"
15
16static inline unsigned rotateL(unsigned x, unsigned n){
17 return ((x << n) | (x >> (32 - n)));
18}
19
20static inline unsigned rotateR(unsigned x, unsigned n){
21 return ((x >> n) | (x << (32 - n)));
22}
23
24// finds the end position of largest sequence of zeros in binary representation
25// of 'immediate'.
26static int findLargestZeroSequence(unsigned immediate){
27 int max_zero_pos = 0;
28 int max_zero_length = 0;
29 int zero_pos;
30 int zero_length;
31 int pos = 0;
32 int end_pos;
33
34 while ((immediate & 0x3) == 0) {
35 immediate = rotateR(immediate, 2);
36 pos+=2;
37 }
38 end_pos = pos+32;
39
40 while (pos<end_pos){
41 while (((immediate & 0x3) != 0)&&(pos<end_pos)) {
42 immediate = rotateR(immediate, 2);
43 pos+=2;
44 }
45 zero_pos = pos;
46 while (((immediate & 0x3) == 0)&&(pos<end_pos)) {
47 immediate = rotateR(immediate, 2);
48 pos+=2;
49 }
50 zero_length = pos - zero_pos;
51 if (zero_length > max_zero_length){
52 max_zero_length = zero_length;
53 max_zero_pos = zero_pos % 32;
54 }
55
56 }
57
58 return (max_zero_pos + max_zero_length) % 32;
59}
60
61std::vector<unsigned> splitImmediate(unsigned immediate){
62 std::vector<unsigned> immediatePieces;
63
64 if (immediate == 0){
65 immediatePieces.push_back(0);
66 } else {
67 int start_pos = findLargestZeroSequence(immediate);
68 unsigned immediate_tmp = rotateR(immediate, start_pos);
69 int pos = 0;
70 while (pos < 32){
71 while(((immediate_tmp&0x3) == 0)&&(pos<32)){
72 immediate_tmp = rotateR(immediate_tmp,2);
73 pos+=2;
74 }
75 if (pos < 32){
76 immediatePieces.push_back(rotateL(immediate_tmp&0xFF,
77 (start_pos + pos) % 32 ));
78 immediate_tmp = rotateR(immediate_tmp,8);
79 pos+=8;
80 }
81 }
82 }
83 return immediatePieces;
84}