Войти
ПрограммированиеФорумОбщее

Помогите настроить таргеты компиляции Clang (7 стр)

Страницы: 13 4 5 6 7 8 Следующая »
#90
(Правка: 17:10) 17:02, 3 ноя. 2019

DevilDevil

Проще всего смотреть через -S, как генерируется ассемблерный листинг в данном конкретном случае и делать так же. При этом, если листинг немного поправить, путем удаления нескольких строк, clang с правильным таргетом должен его успешно компилировать.


#91
17:52, 3 ноя. 2019

CgReligion

Посмотри локально, пожалуйста :)
Я с этим долго промучаюсь

#92
(Правка: 18:44) 18:38, 3 ноя. 2019

DevilDevil

Вот так компилируется пример выше, если префикс локальной метки заменить на L:

сlang --target=armv7m-none-ios-gnueabi -march=armv7m -c main.c

Или вариант без ассемблерных подстановок:

        .globl     _func
_func:
        eor        r0, 0
        cmp        r0, 0
        beq        done
        eor        r0, 0
done:   bx         lr
        .end

clang --target=armv7m-none-ios-gnueabi -o boo.o -c boo.s
#93
18:44, 3 ноя. 2019

CgReligion

Так про L никто не говорил
L действительно собирается

А как сделать точку или хотябы .L?

#94
(Правка: 19:36) 19:07, 3 ноя. 2019

DevilDevil

.L — можно только для ELF-файлов. В документации по ассемблеру GNU сказано, что локальные символы начинаются со специального префикса, которым для традиционных UNIX систем являлся L. Объектные файлы для IOS имею формат Mach-O, который по прямой линии родственен классическому a.out — формату из мира UNIX. То есть для них префиксом локальных символов является только  L, если нет каких либо явных изменений в реализации. Судя по всему, clang/GAS следуют традиции.

#95
19:29, 3 ноя. 2019

CgReligion

Спасибо
Странно, что годболд не ругается

#96
19:37, 3 ноя. 2019

CgReligion

Окей.
У меня из исходника идёт обращение к внешней (на Delphi) функции.
Вот её описание:

void TinyThrowSafeCall(int32_t code, void* return_address);

Есть такой код. На него ругается (iOS32 и iOS64), как быть?

    "L.check_safecall: \n\t"
        "mov r1, lr \n\t"
        "cmp r0, 0 \n\t"
        "blt TinyThrowSafeCall \n\t"

#97
(Правка: 21:17) 20:48, 3 ноя. 2019

DevilDevil

В последней строчке, на сколько я понял, вызов по условию предполагается. Он скорее всего определен только для ближних переходов. Для вызова внешней функции нужно использовать bl.

#98
21:40, 3 ноя. 2019

CgReligion

Я конечно попробую. Но идея как раз в этом. Прыгнуть если выполнилось условие )

Ну и потом bl портит регистр lr )

#99
(Правка: 22:25) 22:16, 3 ноя. 2019

DevilDevil

Тогда можно после условия переходить на локальную метку, а из неё уже прыгать через b (аналог jmp для x86-кода) по адресу внешней функции. Встретившаяся команда возврата внешней функции приведёт к немедленному выходу из функции-обёртки.

#100
1:51, 4 ноя. 2019

CgReligion

Это странно. Но это компилируется
Спасибо большое!

Завтра проверю работоспособность :)

#101
16:13, 6 ноя. 2019

Хм.

Возник вопрос
Вот для Win64 long double 16 байт. Всё норм.
Но можно ли сделать так, чтобы long double возвращался в st(0)?

https://godbolt.org/z/YyePA_

//__attribute__ ((ms_abi))
long double test()
{
    return 0;
}
test: # @test
   // Win64
  mov rax, rcx
  fldz
  fstp tbyte ptr [rcx]
  ret
test: # @test
  // Linux/MacOS +
  fldz
  ret
#102
(Правка: 13:10) 13:03, 7 ноя. 2019

DevilDevil

> Но можно ли сделать так, чтобы long double возвращался в st(0)?
Ни один нормальный компилятор так делать не будет, потому как это противоречит соглашению о вызовах функций для 64-битных Windows. Возврат результата вещественного значения там определяется через XMM-регистр. Структуры, которые не помещаются в целый регистр, передаются через указатель на память [rcx]. Подготовка последнего обеспечивается вызывающей функцией. Стек регистров FPU может быть использован внутри функции, но передача значений через его регистры между функциями неопределенна. Сохранить значение в st(0), конечно, можно, но это сделает её правильный вызов из любой другой нормальной функции невозможным.

Вообще, думаю, что тему можно закрыть, потому как она уже не имеет никакого отношения к clang.

#103
16:28, 7 ноя. 2019

CgReligion

Напротив
Вопрос как раз по таргетам Clang
Насчёт "ни один вменяемый компилятор" не знаю, что сказать.
Делать настолько непрозрачную и недокументированную систему таргетирования - тоже не совсем адекватно. Как по мне :)

Насчёт long double... Си всегда позиционировался как низкоуровневый. Не вижу причин, чтобы не добавить такую возможность :)

#104
(Правка: 20:49) 19:30, 7 ноя. 2019

DevilDevil

Таргет задаёт ABI и используемое соглашение о вызовах. В принципе ABI точно можно определить уже по двум параметрам таргета: системе команд процессора и операционной системе. Но для некоторых операционных систем одного семейства, ABI тоже может отличаться. Поэтому оно также задаётся в таргете. Для 64-битных Windows это всё не имеет никакого значения, потому как там определено одно ABI, а соглашение о вызовах (Microsoft x64 calling convention) однозначно определяет правила передачи аргументов в функцию через регистры и прочее. Любой другой компилятор для Windows (MSVC, GCC, ICC) будет генерировать код согласно требованиям ABI для данной системы без малейшего исключения.

При задании неверного таргета clang скромно молчит, не выдавая никаких сообщений. Это, конечно, нехорошо. Строгой типизации в задании параметров таргета нет. Но с другой стороны сами идеи задания абстрактной цели сборки были заложены задолго до появления любой современной 64-х битной архитектуры. Формат таргетов был заимствован из компилятора проекта GCC. Но в GCC предполагалось, что программист самостоятельно собирает из исходных кодов себе компилятор, задавая целевую платформу через указания таргета при сборке. Выращенный таким образом компилятор может генерировать код, только под определённую архитектуру. Clang изначально планировался, как замена GCC, но с предусловием, что он cможет генерировать код под любую поддерживаемую им платформу в не зависимости от опций, которыми он собирался.

> Насчёт long double... Си всегда позиционировался как низкоуровневый.
Си создавался, как высокоуровневый язык для реализации первых систем UNIX. Это происходило в начале-середине 70-х годов прошлого столетия. Потом до принятия стандарта прошло ещё около 15-и лет. В результате получилось то, что размеры вещественных и прочих типов всё равно могут быть разными. Так определено в Стандарте. Типы зависят от конкретной реализации (компиляторов, процессоров, ОС), которой так славится современный уже низкоуровневый язык Си. Последнее и отражает фрагментацию и отличия в низкоуровневом коде везде, где это возможно. То есть везде.

Вот примерный список таргетов: https://gcc.gnu.org/install/specific.html. Или вариация для clang попроще: https://clang.llvm.org/docs/CrossCompilation.html. Но в данном случае это всё не важно, потому, как здесь дело совсем не в таргетах.

Страницы: 13 4 5 6 7 8 Следующая »
ПрограммированиеФорумОбщее