mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-10 18:37:01 +00:00
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33141 91177308-0d34-0410-b5e6-96231b3b80d8
85 lines
2.2 KiB
C++
85 lines
2.2 KiB
C++
//===-- ARMCommon.cpp - Define support functions for ARM --------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file was developed by the "Instituto Nokia de Tecnologia" and
|
|
// is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "ARMCommon.h"
|
|
|
|
static inline unsigned rotateL(unsigned x, unsigned n){
|
|
return ((x << n) | (x >> (32 - n)));
|
|
}
|
|
|
|
static inline unsigned rotateR(unsigned x, unsigned n){
|
|
return ((x >> n) | (x << (32 - n)));
|
|
}
|
|
|
|
// finds the end position of largest sequence of zeros in binary representation
|
|
// of 'immediate'.
|
|
static int findLargestZeroSequence(unsigned immediate){
|
|
int max_zero_pos = 0;
|
|
int max_zero_length = 0;
|
|
int zero_pos;
|
|
int zero_length;
|
|
int pos = 0;
|
|
int end_pos;
|
|
|
|
while ((immediate & 0x3) == 0) {
|
|
immediate = rotateR(immediate, 2);
|
|
pos+=2;
|
|
}
|
|
end_pos = pos+32;
|
|
|
|
while (pos<end_pos){
|
|
while (((immediate & 0x3) != 0)&&(pos<end_pos)) {
|
|
immediate = rotateR(immediate, 2);
|
|
pos+=2;
|
|
}
|
|
zero_pos = pos;
|
|
while (((immediate & 0x3) == 0)&&(pos<end_pos)) {
|
|
immediate = rotateR(immediate, 2);
|
|
pos+=2;
|
|
}
|
|
zero_length = pos - zero_pos;
|
|
if (zero_length > max_zero_length){
|
|
max_zero_length = zero_length;
|
|
max_zero_pos = zero_pos % 32;
|
|
}
|
|
|
|
}
|
|
|
|
return (max_zero_pos + max_zero_length) % 32;
|
|
}
|
|
|
|
std::vector<unsigned> splitImmediate(unsigned immediate){
|
|
std::vector<unsigned> immediatePieces;
|
|
|
|
if (immediate == 0){
|
|
immediatePieces.push_back(0);
|
|
} else {
|
|
int start_pos = findLargestZeroSequence(immediate);
|
|
unsigned immediate_tmp = rotateR(immediate, start_pos);
|
|
int pos = 0;
|
|
while (pos < 32){
|
|
while(((immediate_tmp&0x3) == 0)&&(pos<32)){
|
|
immediate_tmp = rotateR(immediate_tmp,2);
|
|
pos+=2;
|
|
}
|
|
if (pos < 32){
|
|
immediatePieces.push_back(rotateL(immediate_tmp&0xFF,
|
|
(start_pos + pos) % 32 ));
|
|
immediate_tmp = rotateR(immediate_tmp,8);
|
|
pos+=8;
|
|
}
|
|
}
|
|
}
|
|
return immediatePieces;
|
|
}
|