Сообщения без ответов | Активные темы Текущее время: 28 апр 2024, 17:44



Ответить на тему  [ Сообщений: 7 ] 
 Div1 sh7750 
Автор Сообщение
Сообщение 05 авг 2013, 18:35
Господа, кто-нибудь разбирался с данной инструкцией?
В мануале заявляется, что это ones-tep division integer instruction.
Суть работы этой инструкции том, что она выполняет как бы не полное деление целочсленных операндов, а как бы один шаг алгоритма деления, и благодаря этому, процессор, якобы, во время выполнения инструкции деления может отвечать на прерывания и прочие вещи, требующие незамедлительной обработки (http://resource.renesas.com/lib/eng/e_l ... index.html, "Division instructions").
Сам же алгоритм деления заключается в следующем:
1. Делимое сдвигается влево (в сторону старших разрядов) на один бит.
2. Из получившегося числа вычитается делитель (сложение в complementary-two).

Предположим есть два числа, 79 (0100 1111) и 5 (0101).
1. сдвигаем 79 влево на 1 бит. ((0100 1111)<<1 == 1001 1110).
2. вычитаем 3 (1001 1110 + 1 0011 == 1011 0001 == B1(16)== 177(10), имхо, не сильно похоже на остаток)


Цитата:
In 1-step division, the dividend is shifted 1 bit to the left, the divisor is subtracted from this, and
the quotient bit is reflected in the Q bit according to whether the result is positive or negative.

Я вручную попробовал поделить, и у меня не вышло ничего похожего на результат целочисленного деления.
Пробовал также и псевдокод из мануала гонять, так же ничего похоже на результат не получается, даже после нескольких выполнений инструкции (сначала думал что неправильно перевел псевдокод, я заменял все свичи на if'ы, потом все-таки взял компилятор C и запустил пример из мануала как есть - тот же результат).
Логика работы тоже непонятна.

Код для вставки:
Код:
#include <stdio.h>

static signed int R[15];

static unsigned int Q,M,T,PC;
//m - divisor, n - dividented number
//Rn = Rn/Rm;
void DIV1(char m, char n) /* DIV1 Rm,Rn */
{
    unsigned long tmp0, tmp2;
    unsigned char old_q, tmp1;
    old_q=Q;
    //sign into Q
    if(((0x80000000 & R[n])!=0))
        { Q=1; }
    tmp2 = R[m]; //divisor
    R[n]<<=1; //divident<<=1;
    R[n]|=(unsigned long)T; //or with T bit. wtf is that needed. carry?
    switch(old_q)
    {
        case 0:
            switch(M){
            case 0:
                tmp0=R[n]; //divident
                R[n]-=tmp2; //divident -=divisor
                tmp1=(R[n]>tmp0); //if (divident - divisor)> divident, then 1 to tmp1
                switch(Q){
                case 0:
                    Q=tmp1;
                    break;
                case 1:
                    Q=(unsigned char)(tmp1==0);
                    break;
                }
        break;
        case 1:
            tmp0=R[n];
            R[n]+=tmp2;
            tmp1=(R[n]<tmp0);
                switch(Q){
                    case 0:
                        Q=(unsigned char)(tmp1==0);
                    break;
                    case 1:
                        Q=tmp1;
                    break;
                }
            break;
        }
    break;
    case 1:

        switch(M)
        {
            case 0:
                tmp0=R[n];
                R[n]+=tmp2;
                tmp1=(R[n]<tmp0);
                switch(Q){
                case 0:
                    Q=tmp1;
                break;
                case 1:
                    Q=(unsigned char)(tmp1==0);
                break;
                }
            break;
            case 1:
                tmp0=R[n];
                R[n]-=tmp2;
                tmp1=(R[n]>tmp0);
                    switch(Q){
                        case 0:Q=(unsigned char)(tmp1==0);
                    break;
                        case 1:Q=tmp1;
                    break;
                    }
            break;
        }
        break;
    }
if(Q==M) T=1;
else T=0;
PC+=2;

}

void DIV0U() {
M=Q=T=0;
}

void SHLL16(int reg) {
R[reg]<<=16;
}

void EXTUW(char src, char dest) {
    R[dest] = R[src]&0x0000FFFF;
}

main()
{
    const int divident = 35;
    const int divisor = 5;
    R[0] = divisor;
    R[1] = divident;
    printf("Before:\n");
    printf("Divisor, R[0]=%d\n", R[0]);
    printf("Divident, R[1]=%d\n", R[1]);
    SHLL16(0);// R0 ;Set divisor in upper 16 bits, clear lower 16 bits to 0
              //TST R0,R0 ;Check for division by zero
              //BT ZERO_DIV ;
              //CMP/HS R0,R1 ;Check for overflow
              //BT OVER_DIV ;
            printf("R[0] after SHLL 0x%x\n", R[0]);
            DIV0U();    //DIV0U ;Flag initialization
            //.arepeat 16 ;
            int i=0;
            for (i = 0; i < 16; i++)
            {
                    DIV1(0, 1);    //DIV1 R0,R1 ;Repeat 16 times
                    //.aendr ;
                    //ROTCL R1 ;
            }
            EXTUW(1, 1);  //R1 = quotient
    //Result in regsiter #1
    printf("After:\n");
    printf("R[0]=%d\n", R[0]);
    printf("Quotient: R[1]=%d, while must be %d\n", R[1], divident/divisor);

}


Буду благодарен любой помощи или наводке, ибо я не вкуриваю алгоритм этой инструкции вообще.


Сообщение 06 авг 2013, 06:25
Профиль
Аватара пользователя

Зарегистрирован:
24 июл 2007, 06:54
Сообщения: 492
Откуда: Embedded
А написать простенькую программку на АСМе на целевой процессор с выводом результата религия не позволяет? Обязательно надо штудировать зачастую неточные источники информации?

_________________
Tried so hard and got so far, but in the end, it doesn't even matter...


Сообщение 06 авг 2013, 09:16
Профиль ICQ
Аватара пользователя

Зарегистрирован:
28 дек 2012, 05:58
Сообщения: 19
Откуда: Курган
Чтобы пример из мануала заработал, надо перед выводом добавить забытую команду ROTCL - "проворачивание" влево через бит T. Я так понял, что команда DIV1 за каждый проход вычисляет один бит частного - T, который зависит от знака "остатка" - Q. После последнего её выполнения младший бит частного остаётся в Т.

Документация мутная какая-то. Совет написать программку на проц (если есть возможность) - очень дельный.


Сообщение 06 авг 2013, 15:45
Цитата:
А написать простенькую программку на АСМе на целевой процессор с выводом результата религия не позволяет? Обязательно надо штудировать зачастую неточные источники информации?

Почему, позволяет. Только для это слишком много телодвижений нужно сделать, чтобы эту простенькую программу в него залить.
Цитата:
Обязательно надо штудировать зачастую неточные источники информации?

Ну если уж официальный мануал от самого производителя - неточный источник, то что уже тогда называть точным???


Сообщение 06 авг 2013, 23:01
Профиль ICQ WWW
Аватара пользователя

Зарегистрирован:
24 июл 2007, 10:41
Сообщения: 570
Вот ещё мануал из Dreamcast SDK : http://ogamespec.com/download/SHC_PM.pdf


Сообщение 07 авг 2013, 06:11
Профиль ICQ
Аватара пользователя

Зарегистрирован:
28 дек 2012, 05:58
Сообщения: 19
Откуда: Курган
rdc писал(а):
Ну если уж официальный мануал от самого производителя - неточный источник, то что уже тогда называть точным???
Ошибки в документации - обычное явление. Хорошо, если её оперативно исправляют.
Ну доки даже ещё ничего, вот примеры кода (или библиотеки) у производителей процессоров частенько такие, что ...


Сообщение 09 авг 2013, 14:14
Профиль ICQ WWW
Аватара пользователя

Зарегистрирован:
22 июл 2007, 11:16
Сообщения: 787
Код:
0C176ECC   62F6  MOV.L     @R15+, R2       
0C176EE4   2008  TST       R0, R0
0C176EE6   2F26  MOV.L     R2, @-R15
0C176EE8   8945  BT        h'0C176F76     
0C176EEA   E200  MOV       #h'00, R2
0C176EEC   0019  DIV0U
0C176EEE   4124  ROTCL     R1
0C176EF0   3204  DIV1      R0, R2
0C176EF2   4124  ROTCL     R1
0C176EF4   3204  DIV1      R0, R2
0C176EF6   4124  ROTCL     R1
0C176EF8   3204  DIV1      R0, R2
0C176EFA   4124  ROTCL     R1
0C176EFC   3204  DIV1      R0, R2
0C176EFE   4124  ROTCL     R1
0C176F00   3204  DIV1      R0, R2
0C176F02   4124  ROTCL     R1
0C176F04   3204  DIV1      R0, R2
0C176F06   4124  ROTCL     R1
0C176F08   3204  DIV1      R0, R2
0C176F0A   4124  ROTCL     R1
0C176F0C   3204  DIV1      R0, R2
0C176F0E   4124  ROTCL     R1
0C176F10   3204  DIV1      R0, R2
0C176F12   4124  ROTCL     R1
0C176F14   3204  DIV1      R0, R2
0C176F16   4124  ROTCL     R1
0C176F18   3204  DIV1      R0, R2
0C176F1A   4124  ROTCL     R1
0C176F1C   3204  DIV1      R0, R2
0C176F1E   4124  ROTCL     R1
0C176F20   3204  DIV1      R0, R2
0C176F22   4124  ROTCL     R1
0C176F24   3204  DIV1      R0, R2
0C176F26   4124  ROTCL     R1
0C176F28   3204  DIV1      R0, R2
0C176F2A   4124  ROTCL     R1
0C176F2C   3204  DIV1      R0, R2
0C176F2E   4124  ROTCL     R1
0C176F30   3204  DIV1      R0, R2
0C176F32   4124  ROTCL     R1
0C176F34   3204  DIV1      R0, R2
0C176F36   4124  ROTCL     R1
0C176F38   3204  DIV1      R0, R2
0C176F3A   4124  ROTCL     R1
0C176F3C   3204  DIV1      R0, R2
0C176F3E   4124  ROTCL     R1
0C176F40   3204  DIV1      R0, R2
0C176F42   4124  ROTCL     R1
0C176F44   3204  DIV1      R0, R2
0C176F46   4124  ROTCL     R1
0C176F48   3204  DIV1      R0, R2
0C176F4A   4124  ROTCL     R1
0C176F4C   3204  DIV1      R0, R2
0C176F4E   4124  ROTCL     R1
0C176F50   3204  DIV1      R0, R2
0C176F52   4124  ROTCL     R1
0C176F54   3204  DIV1      R0, R2
0C176F56   4124  ROTCL     R1
0C176F58   3204  DIV1      R0, R2
0C176F5A   4124  ROTCL     R1
0C176F5C   3204  DIV1      R0, R2
0C176F5E   4124  ROTCL     R1
0C176F60   3204  DIV1      R0, R2
0C176F62   4124  ROTCL     R1
0C176F64   3204  DIV1      R0, R2
0C176F66   4124  ROTCL     R1
0C176F68   3204  DIV1      R0, R2
0C176F6A   4124  ROTCL     R1
0C176F6C   3204  DIV1      R0, R2
0C176F6E   4124  ROTCL     R1
0C176F70   6013  MOV       R1, R0
0C176F72   000B  RTS
0C176F74   62F6  MOV.L     @R15+, R2       


берем любой готовый код и вынимаем процедуру деления. делаем в точности, как указано. ротсл там не просто так стоят

_________________
1. Модератор всегда прав.
2. Если модератор не прав, см. п. 1.


Показать сообщения за:  Поле сортировки  
Ответить на тему   [ Сообщений: 7 ] 

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 46


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF (mod by Zeru-j).
Русская поддержка phpBB