Lauro Ramos Venancio | a38bbf7 | 2007-01-12 20:35:49 +0000 | [diff] [blame] | 1 | //===-- 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 | |
| 16 | static inline unsigned rotateL(unsigned x, unsigned n){ |
| 17 | return ((x << n) | (x >> (32 - n))); |
| 18 | } |
| 19 | |
| 20 | static 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'. |
| 26 | static 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 | |
| 61 | std::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 | } |