📄 mcomp.cpp
字号:
/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The Core Pocket Media Player
* Copyright (c) 2004-2005 Gabor Kovacs
*
****************************************************************************/
#include "Rules.h"
//----------------------------
//#define USE_PLD
#if defined _WIN32_WCE || defined __PALMOS__
#define USE_IDCT_WMMX
#endif
//----------------------------
#ifdef ARM
#include "DynamicArmCode.h"
//----------------------------
static void PreLoad(C_dyn_code &dc, bool ARM5, int Pos){
#ifdef USE_PLD
if(ARM5){
if(Pos >= 0){
if(Pos > 0){
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Add(dc.r0, dc.r0, 8);
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Sub(dc.r0, dc.r0, 8);
}else{
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Add(dc.r0, dc.r0, 4);
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Sub(dc.r0, dc.r0, 4);
}
}else{
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Add(dc.r0, dc.r0, 7);
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Sub(dc.r0, dc.r0, 7);
}
}
#endif
}
//----------------------------
static void PreLoad2Init(C_dyn_code &dc, bool ARM5, int Pos){
#ifdef USE_PLD
if(ARM5){
if(Pos >= 0){
if(Pos > 0){
dc.Add(dc.r10, dc.r2, dc.r2);
dc.Add(dc.r10, dc.r10, 8);
}else{
dc.Add(dc.r10, dc.r2, dc.r2);
dc.Add(dc.r10, dc.r10, 4);
}
}else{
dc.Add(dc.r10, dc.r2, dc.r2);
dc.Add(dc.r10, dc.r10, 7);
}
}
#endif
}
//----------------------------
static void PreLoad2(C_dyn_code &dc, bool ARM5, int Pos){
#ifdef USE_PLD
if(ARM5){
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
dc.Pld(dc.r0, dc.r10);
}
#endif
}
//----------------------------
static void AddBlockRow(C_dyn_code &dc, int Pos){
if(Pos < 0){
dc.Byte(); dc.Ldr(dc.r4, dc.r0, 0);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 1);
dc.Byte(); dc.Ldr(dc.r5, dc.r0, 4);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 5);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 6);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 3);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 7);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 24);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 24);
}else{
if(Pos > 0){
dc.Ldr(dc.r5, dc.r0, 8);
dc.Ldr(dc.r6, dc.r0, 4);
dc.LdrAdvance(dc.r4, dc.r0, dc.r2);
dc.Mov(dc.r5, dc.r5, dc.LSL, 32-Pos);
dc.Orr(dc.r5, dc.r5, dc.r6, dc.LSR, Pos);
dc.Mov(dc.r4, dc.r4, dc.LSR, Pos);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 32-Pos);
}else{
dc.Ldr(dc.r5, dc.r0, 4);
dc.LdrAdvance(dc.r4, dc.r0, dc.r2);
}
}
dc.Ldr(dc.r7, dc.r1, 4);
dc.Ldr(dc.r6, dc.r1, 0);
dc.And(dc.r9, dc.r12, dc.r5, dc.LSR, 1);
dc.And(dc.r8, dc.r12, dc.r4, dc.LSR, 1);
dc.Orr(dc.r5, dc.r7, dc.r5);
dc.Orr(dc.r4, dc.r6, dc.r4);
dc.And(dc.r7, dc.r12, dc.r7, dc.LSR, 1);
dc.And(dc.r6, dc.r12, dc.r6, dc.LSR, 1);
dc.Add(dc.r7, dc.r7, dc.r9);
dc.Add(dc.r6, dc.r6, dc.r8);
dc.And(dc.r5, dc.r5, dc.r14);
dc.And(dc.r4, dc.r4, dc.r14);
dc.Add(dc.r7, dc.r7, dc.r5);
dc.Add(dc.r6, dc.r6, dc.r4);
dc.Str(dc.r7, dc.r1, 4);
dc.StrAdvance(dc.r6, dc.r1, 8);
}
//----------------------------
static void LoadHorRow(C_dyn_code &dc, int Pos){
//result is r4, dc.r5 dc.And(dc.r8, dc.r9 (one pixel to the right)
//r6, dc.r7 can be used
if(Pos < 0){
dc.Byte(); dc.Ldr(dc.r4, dc.r0, 0);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 1);
dc.Byte(); dc.Ldr(dc.r5, dc.r0, 4);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 5);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 6);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 3);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 7);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 24);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 8);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 24);
dc.Mov(dc.r8, dc.r4, dc.LSR, 8);
dc.Mov(dc.r9, dc.r5, dc.LSR, 8);
dc.Orr(dc.r8, dc.r8, dc.r5, dc.LSL, 24);
dc.Orr(dc.r9, dc.r9, dc.r6, dc.LSL, 24);
dc.Add(dc.r0, dc.r0, dc.r2);
}else{
dc.Ldr(dc.r5, dc.r0, 4);
dc.Ldr(dc.r6, dc.r0, 8);
dc.LdrAdvance(dc.r4, dc.r0, dc.r2);
if(Pos+8 < 32){
dc.Mov(dc.r9, dc.r5, dc.LSR, Pos+8);
dc.Orr(dc.r9, dc.r9, dc.r6, dc.LSL, 32-Pos-8);
dc.Mov(dc.r8, dc.r4, dc.LSR, Pos+8);
dc.Orr(dc.r8, dc.r8, dc.r5, dc.LSL, 32-Pos-8);
}else{
dc.Mov(dc.r8, dc.r5);
dc.Mov(dc.r9, dc.r6);
}
if(Pos > 0){
dc.Mov(dc.r4, dc.r4, dc.LSR, Pos);
dc.Mov(dc.r6, dc.r6, dc.LSL, 32-Pos);
dc.Orr(dc.r4, dc.r4, dc.r5, dc.LSL, 32-Pos);
dc.Orr(dc.r5, dc.r6, dc.r5, dc.LSR, Pos);
}
}
}
//----------------------------
static void CopyHorRow(C_dyn_code &dc, int Pos, bool round, bool add){
//r14 01010101
//r12 7f7f7f7f
LoadHorRow(dc, Pos);
dc.And(dc.r6, dc.r12, dc.r4, dc.LSR, 1);
dc.And(dc.r7, dc.r12, dc.r5, dc.LSR, 1);
if(round){
dc.And(dc.r4, dc.r4, dc.r8);
dc.And(dc.r5, dc.r5, dc.r9);
}else{
dc.Orr(dc.r4, dc.r4, dc.r8);
dc.Orr(dc.r5, dc.r5, dc.r9);
}
dc.And(dc.r8, dc.r12, dc.r8, dc.LSR, 1);
dc.And(dc.r9, dc.r12, dc.r9, dc.LSR, 1);
dc.And(dc.r4, dc.r4, dc.r14);
dc.And(dc.r5, dc.r5, dc.r14);
dc.Add(dc.r4, dc.r4, dc.r6);
dc.Add(dc.r5, dc.r5, dc.r7);
dc.Add(dc.r4, dc.r4, dc.r8);
dc.Add(dc.r5, dc.r5, dc.r9);
if(add){
dc.Ldr(dc.r7, dc.r1, 4);
dc.Ldr(dc.r6, dc.r1, 0);
dc.And(dc.r9, dc.r12, dc.r5, dc.LSR, 1);
dc.And(dc.r8, dc.r12, dc.r4, dc.LSR, 1);
dc.Orr(dc.r5, dc.r7, dc.r5);
dc.Orr(dc.r4, dc.r6, dc.r4);
dc.And(dc.r7, dc.r12, dc.r7, dc.LSR, 1);
dc.And(dc.r6, dc.r12, dc.r6, dc.LSR, 1);
dc.Add(dc.r7, dc.r7, dc.r9);
dc.Add(dc.r6, dc.r6, dc.r8);
dc.And(dc.r5, dc.r5, dc.r14);
dc.And(dc.r4, dc.r4, dc.r14);
dc.Add(dc.r7, dc.r7, dc.r5);
dc.Add(dc.r6, dc.r6, dc.r4);
dc.Str(dc.r7, dc.r1, 4);
dc.StrAdvance(dc.r6, dc.r1, 8);
}else{
dc.Str(dc.r5, dc.r1, 4);
dc.StrAdvance(dc.r4, dc.r1, dc.r3);
}
}
//----------------------------
static void LoadVerRow(C_dyn_code &dc, int Pos, bool parity){
if(parity){
//result is r8, dc.r9 (r10=r8>>1, dc.r11=r9>>1)
//r10, dc.r11 can be used
if(Pos < 0){
dc.Byte(); dc.Ldr(dc.r8, dc.r0, 0);
dc.Byte(); dc.Ldr(dc.r10, dc.r0, 1);
dc.Byte(); dc.Ldr(dc.r9, dc.r0, 4);
dc.Byte(); dc.Ldr(dc.r11, dc.r0, 5);
dc.Orr(dc.r8, dc.r8, dc.r10,dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r10, dc.r0, 2);
dc.Orr(dc.r9, dc.r9, dc.r11, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r11, dc.r0, 6);
dc.Orr(dc.r8, dc.r8, dc.r10, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r10, dc.r0, 3);
dc.Orr(dc.r9, dc.r9, dc.r11, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r11, dc.r0, 7);
dc.Orr(dc.r8, dc.r8, dc.r10, dc.LSL, 24);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Orr(dc.r9, dc.r9, dc.r11, dc.LSL, 24);
}else{
if(Pos > 0){
dc.Ldr(dc.r9, dc.r0, 8);
dc.Ldr(dc.r10, dc.r0, 4);
dc.LdrAdvance(dc.r8, dc.r0, dc.r2);
dc.Mov(dc.r9, dc.r9, dc.LSL, 32-Pos);
dc.Orr(dc.r9, dc.r9, dc.r10, dc.LSR, Pos);
dc.Mov(dc.r8, dc.r8, dc.LSR, Pos);
dc.Orr(dc.r8, dc.r8, dc.r10, dc.LSL, 32-Pos);
}else{
dc.Ldr(dc.r9, dc.r0, 4);
dc.LdrAdvance(dc.r8, dc.r0, dc.r2);
}
}
dc.And(dc.r11, dc.r12, dc.r9, dc.LSR, 1);
dc.And(dc.r10, dc.r12, dc.r8, dc.LSR, 1);
}else{
//result is r4, dc.r5 (r6=r4>>1, dc.r7=r5>>1)
//r6, dc.r7 can be used
if(Pos < 0){
dc.Byte(); dc.Ldr(dc.r4, dc.r0, 0);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 1);
dc.Byte(); dc.Ldr(dc.r5, dc.r0, 4);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 5);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 6);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 3);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 16);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 7);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 24);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 24);
}else{
if(Pos > 0){
dc.Ldr(dc.r5, dc.r0, 8);
dc.Ldr(dc.r6, dc.r0, 4);
dc.LdrAdvance(dc.r4, dc.r0, dc.r2);
dc.Mov(dc.r5, dc.r5, dc.LSL, 32-Pos);
dc.Orr(dc.r5, dc.r5, dc.r6, dc.LSR, Pos);
dc.Mov(dc.r4, dc.r4, dc.LSR, Pos);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 32-Pos);
}else{
dc.Ldr(dc.r5, dc.r0, 4);
dc.LdrAdvance(dc.r4, dc.r0, dc.r2);
}
}
dc.And(dc.r7, dc.r12, dc.r5, dc.LSR, 1);
dc.And(dc.r6, dc.r12, dc.r4, dc.LSR, 1);
}
}
//----------------------------
static void CopyVerRow(C_dyn_code &dc, int Pos, bool parity, bool round, bool add){
//r14 01010101
//r12 7f7f7f7f
LoadVerRow(dc, Pos, parity);
if(parity){
if(round){
dc.And(dc.r4, dc.r4, dc.r8);
dc.And(dc.r5, dc.r5, dc.r9);
}else{
dc.Orr(dc.r4, dc.r4, dc.r8);
dc.Orr(dc.r5, dc.r5, dc.r9);
}
dc.And(dc.r4, dc.r4, dc.r14);
dc.And(dc.r5, dc.r5, dc.r14);
dc.Add(dc.r4, dc.r4, dc.r6);
dc.Add(dc.r5, dc.r5, dc.r7);
dc.Add(dc.r4, dc.r4, dc.r10);
dc.Add(dc.r5, dc.r5, dc.r11);
if(add){
dc.Ldr(dc.r7, dc.r1, 4);
dc.Ldr(dc.r6, dc.r1, 0);
dc.And(dc.r3, dc.r12, dc.r5, dc.LSR, 1);
dc.Orr(dc.r5, dc.r7, dc.r5);
dc.And(dc.r7, dc.r12, dc.r7, dc.LSR, 1);
dc.Add(dc.r7, dc.r7, dc.r3);
dc.And(dc.r3, dc.r12, dc.r4, dc.LSR, 1);
dc.Orr(dc.r4, dc.r6, dc.r4);
dc.And(dc.r6, dc.r12, dc.r6, dc.LSR, 1);
dc.Add(dc.r6, dc.r6, dc.r3);
dc.And(dc.r5, dc.r5, dc.r14);
dc.And(dc.r4, dc.r4, dc.r14);
dc.Add(dc.r5, dc.r5, dc.r7);
dc.Add(dc.r4, dc.r4, dc.r6);
dc.Ldr(dc.r7, dc.sp, 0); //end src for loop compare
dc.Str(dc.r5, dc.r1, 4);
dc.StrAdvance(dc.r4, dc.r1, 8);
}else{
dc.Ldr(dc. r7, dc.sp, 0); //end src for loop compare
dc.Str(dc.r5, dc.r1, 4);
dc.StrAdvance(dc.r4, dc.r1, dc.r3);
}
}else{
if(round){
dc.And(dc.r8, dc.r8, dc.r4);
dc.And(dc.r9, dc.r9, dc.r5);
}else{
dc.Orr(dc.r8, dc.r8, dc.r4);
dc.Orr(dc.r9, dc.r9, dc.r5);
}
dc.And(dc.r8, dc.r8, dc.r14);
dc.And(dc.r9, dc.r9, dc.r14);
dc.Add(dc.r8, dc.r8, dc.r10);
dc.Add(dc.r9, dc.r9, dc.r11);
dc.Add(dc.r8, dc.r8, dc.r6);
dc.Add(dc.r9, dc.r9, dc.r7);
if(add){
dc.Ldr(dc.r11, dc.r1, 4);
dc.Ldr(dc.r10, dc.r1, 0);
dc.And(dc.r3, dc.r12, dc.r9, dc.LSR, 1);
dc.Orr(dc.r9, dc.r11, dc.r9);
dc.And(dc.r11, dc.r12, dc.r11, dc.LSR, 1);
dc.Add(dc.r11, dc.r11, dc.r3);
dc.And(dc.r3, dc.r12, dc.r8, dc.LSR, 1);
dc.Orr(dc.r8, dc.r10, dc.r8);
dc.And(dc.r10, dc.r12, dc.r10, dc.LSR, 1);
dc.Add(dc.r10, dc.r10, dc.r3);
dc.And(dc.r9, dc.r9, dc.r14);
dc.And(dc.r8, dc.r8, dc.r14);
dc.Add(dc.r11, dc.r11, dc.r9);
dc.Add(dc.r10, dc.r10, dc.r8);
dc.Str(dc.r11, dc.r1, 4);
dc.StrAdvance(dc.r10, dc.r1, 8);
}else{
dc.Str(dc.r9, dc.r1, 4);
dc.StrAdvance(dc.r8, dc.r1, dc.r3);
}
}
}
//----------------------------
// load needs r2, dc.r3 for temporary (r2 is restored from stack)
static void LoadHorVerRow(C_dyn_code &dc, int Pos, bool parity){
if(parity){
//read result r4, dc.r5 dc.And(dc.r2, dc.r3 (one pixel to right)
//r6, dc.r7 can be used
if(Pos<0){
dc.Byte(); dc.Ldr(dc.r4, dc.r0, 0);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 1);
dc.Byte(); dc.Ldr(dc.r5, dc.r0, 4);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 5);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r6, dc.r0, 2);
dc.Orr(dc.r5, dc.r5, dc.r7, dc.LSL, 8);
dc.Byte(); dc.Ldr(dc.r7, dc.r0, 6);
dc.Orr(dc.r4, dc.r4, dc.r6, dc.LSL, 16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -