Компилятор XC16 - встроенное ограничение сборки для создания операнда памяти для BTSTS (косвенная адресация памяти) - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь создать высокоуровневый метод для вызова инструкции BTSTS.

Что я пробовал до сих пор:

volatile unsigned int a = 1;
asm volatile(
    "btsts %0, #2\n"
    : "+d" (b)
    : 
    : "cc"
);

Выше выдает следующий сборочный вывод:

mov #1,w0
mov w0,[w14]
mov [w14],w0
mov w0,w1

btsts   w1, #2

mov w1,w0
mov w0,[w14]

Но это не то, что я хочу. Бит должен быть установлен непосредственно в памяти, чтобы инструкция была атомарной:

btsts   [w0], #2

Как правильно ее достичь?

Ближайший подход был следующий:

Здесь «а» - это глобальная переменная вместо локальной переменной

asm volatile(
    "btsts [%0], #2\n"
    :
    : "d" (&a)
    : "cc"
);

На этот раз генерируется следующий вывод сборки:

mov _a,w0
mov w0,w1
btsts [w1], #2

Это немного лучше, однако я не хочу явно указывать скобки [% 0] вокруг него. Разве нет способа, которым компилятор / ассемблер узнает, что требуется косвенная адресация памяти?

Редактировать: я попробовал еще одну вещь. Несмотря на то, что ограничение «m» не упоминалось в документации, я попробовал его

volatile unsigned int r = 0;
void test(volatile unsigned int* t) {
       asm (
       "btsts %0, #2\n"
       : "+m" (t)
   );
}

выше будет производить что-то вроде

mov #_r,w0 
...
mov w0,[w14]
btsts [w14], #2

Это также неверно и не изменится r. Может быть, ограничение "m" не упоминается, потому что оно глючит?

Btw. правильный код будет

btsts [w0], #2

или что-то вроде

mov w0,[w14]
mov [w14],w1
btsts [w1], #2

1 Ответ

0 голосов
/ 24 января 2019

Как-то так?

unsigned short a __at((0x100)) = 1;

int main()
{
   asm (
       "btsts %0, #2\n"
       : "+m" (a)
   );
   return a;
}

Сборка с xc16-gcc -mcci -O1 -mcpu = 30F4011 -S mc

_main:
        .set ___PA___,0
        btsts   _a, #2

        mov     _a,w0
        return
...