1. C++ / Говнокод #27456

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    // https://llvm.org/doxygen/AArch64AddressingModes_8h_source.html#l00051
    
     /// getShiftName - Get the string encoding for the shift type.
     static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) {
       switch (ST) {
       default: llvm_unreachable("unhandled shift type!");
       case AArch64_AM::LSL: return "lsl";
       case AArch64_AM::LSR: return "lsr";
       case AArch64_AM::ASR: return "asr";
       case AArch64_AM::ROR: return "ror";
       case AArch64_AM::MSL: return "msl";
       case AArch64_AM::UXTB: return "uxtb";
       case AArch64_AM::UXTH: return "uxth";
       case AArch64_AM::UXTW: return "uxtw";
       case AArch64_AM::UXTX: return "uxtx";
       case AArch64_AM::SXTB: return "sxtb";
       case AArch64_AM::SXTH: return "sxth";
       case AArch64_AM::SXTW: return "sxtw";
       case AArch64_AM::SXTX: return "sxtx";
       }
       return nullptr;
     }

    Хорош ли тот язык, в котором такую херню надо писать?

    Именно поэтому я за гомоиконы.

    Запостил: j123123, 06 Июня 2021

    Комментарии (50) RSS

    • И да, часто слышу возгласы, что вот в GCC код такой запутанный и непонятный, черт ногу сломит, то ли дело LLVM. Так вот хренушки. Я смотрю код этого LLVM и я б не сказал, что это сильно проше макроговнокода из GCC
      Ответить
    • https://llvm.org/doxygen/X86TargetTransformInfo_8cpp_source.html
      Так, что тут у нас?
      /// About Cost Model numbers used below it's necessary to say the following:
      /// the numbers correspond to some "generic" X86 CPU instead of usage of
      /// concrete CPU model. Usually the numbers correspond to CPU where the feature
      /// apeared at the first time. For example, if we do Subtarget.hasSSE42() in
      /// the lookups below the cost is based on Nehalem as that was the first CPU
      /// to support that feature level and thus has most likely the worst case cost.

      Да, это конечно гениальная идея, тупо назначить каким-то инструкциям "стоимость", и оптимизировать так, чтоб стоимость была минимальной под некий "Generic" CPU.

      И конечно же хуй знает откуда взятые значения этой самой "стоимости":
      static const CostTblEntry SLMCostTable[] = {
          { ISD::MUL,   MVT::v4i32, 11 }, // pmulld
          { ISD::MUL,   MVT::v8i16, 2  }, // pmullw
          { ISD::MUL,   MVT::v16i8, 14 }, // extend/pmullw/trunc sequence.
          { ISD::FMUL,  MVT::f64,   2  }, // mulsd
          { ISD::FMUL,  MVT::v2f64, 4  }, // mulpd
          { ISD::FMUL,  MVT::v4f32, 2  }, // mulps
          { ISD::FDIV,  MVT::f32,   17 }, // divss
          { ISD::FDIV,  MVT::v4f32, 39 }, // divps
          { ISD::FDIV,  MVT::f64,   32 }, // divsd
          { ISD::FDIV,  MVT::v2f64, 69 }, // divpd
          { ISD::FADD,  MVT::v2f64, 2  }, // addpd
          { ISD::FSUB,  MVT::v2f64, 2  }, // subpd
      ...

      которые вряд ли кто пересматривает. Схуя б не сделать некий конфигурационный файл с этими стоимостями, и чтобы кто-то мог легко эти говностоимости в конфиге поменять и пересобрать, померять изменения пирфоманса откомпилированных программ? Хуй там, иди в исходнике ковыряйся, ручками переписывай!
      Ответить
      • ой, кажется у нас портабельная C++ Struct Notation через 3... 2...
        Ответить
      • > Схуя б не сделать некий конфигурационный файл

        Эти яблоумники не осилили отличную от захардкоженной директорию с компилятором, поэтому если вдруг кто-то захочет просто взять и попробовать «LLVM», то придётся либо ебаться и править исходники, либо ебаться и крутить-вертеть директории.
        Ответить
    • Не совсем понял что такое «Гомоиконы», но я за автоген.
      Ответить
      • Гомоиконы -- это лисп. Когда у тебя исходный код и данные представлены одинаково и ты можешь обрабатывать код как данные и исполнять данные как код...
        Ответить
        • показать все, что скрытоГомоикона:
          .                     `.                                   .o-.
          .                    .`           ..```````````..`         . .  .
          .                  `.          ..`               ``.`     .   `.  `
          .                 ..        `.`                     `.`        `.
          .                `.        ..                         `.        `.
          .                -        .`                `..``````..`-        .`
          .               .`       ..                .`          `--        -
          .   Procedure,  -        -                -`             /`       -   Expression,
          .               -        -      Eval     .`    Apply     `-       .`
          .   Arguments   -        :               -                -       .`  Environment
          .               -        /`             .`               -`       -
          .               .`       .:.`         `.`               `-        -
          .                -        ..`.```````.``               `-        .`
          .                `.        .. ```````                 `.        `.
          .                 `.   .     ..                     `.`        `.
          .               `. `.  .       ...               `..`         `.
          .                  . . .          `..``.`.`.``...`          `.`
          .                    `.                                    `.
          Ответить
        • лучше всего исполнять стек как код
          Ответить
          • А ты второй версии или третьей? И ня чём тебя треняровали?
            Ответить
          • Fortщ?
            Ответить
          • >лучше всего исполнять стек как код
            программисты на сишечке так часто делали раньше, и не всегда по собственной воле
            Ответить
            • по моей воле, разумеется
              Ответить
            • Крестовики так и делают, когда используют лямбды.
              Ответить
              • Почему? Лямбды в C++ — это просто сахар няд обычным объектом с перегруженным методом operator(). Никаких особых техник исполнения там нят.
                Ответить
                • Он про gcc'шное расширение для няшной спутал, видимо.
                  Ответить
              • Лямбда "выглядит" как данные, но по сути это обычный код.
                Обычно все (кроме скриптушков) про них так и думают: код.

                Имхо: чтобы исполнять данные как код, нужно ебаца с защитой страниц, и вероятно еще обманывать спекулятивное выполнение, и префетчер, и вряд-ли бы такую важную фичу запилили бы таким грязным неоптимальным хаком
                Ответить
                • Технически лямбда -- это как раз данные. Захваченный контекст + указатель на заранее приготовленный конпелятором код.

                  Если бы она была кодом, то её пришлось бы генерить в rwx страничке. Ну собственно как gcc делает для "лямбд" в няшной, потому что там надо совместимость с обычной функцией.
                  Ответить
                  • А я думал это код, в который вшит указатель на данные
                    Сама лямбда -- код, а её контекст может и данные

                    Ну так знаете обычная процедура тоже код, а её стек -- данные
                    Ответить
                    • Как ты вошьешь данные в код без rwx?

                      Указатель на код в структурку с данными гораздо проще засунуть )))
                      Ответить
                      • ды напрямую, не?

                        MOV RAX, 12345

                        где 12345 это адрес какого-то говна с контекстом (забудем пока про PIC)
                        Ответить
                        • Дык у тебя 100500 инстансов лямбды может быть...

                          Под каждую генерить такой thunk с mov'ом? Ну gcc'шное расширение так и делает, потому что выхода нет.
                          Ответить
                          • всё, дошло

                            Код один, данные разные.

                            Логично один раз сгенерить код, а потом кортежи
                            (данные1, указатель-на-код) , (данныеN, указатель-на-код) положить в секцию данных

                            ну собссно как классы и делаюит, ок
                            Ответить
                            • И собственно поэтому лямбда не лезет в сишный указатель на функцию если она что-то захватывает.
                              Ответить
                              • а если контекста нет, то стандарт гарантирует, что там будет просто функция? или это оптимизирующее свойство компилятора?

                                Блин, захваты контекста такая неоднозначная тема, конечно: в большинстве мейнстрима оно происходит неявно (вот как раз хорошо, что в крестах явно)

                                Обратился к переменной, и сам не заметил.

                                А потом блуждаешь среди ссылок когда память потекла
                                Ответить
                                • Да, должна быть гарантия.

                                  В крестах кстати тоже есть автозахват. Пишешь [&] или [=] и конпелятор сам разберётся что в контекст затащить.
                                  Ответить
                                  • да, но ты можешь явно попросить этово НЕ делать: []


                                    Очень часто мне кложить ничего не нужно, мне нужно просто функцию чтобы сортирнуть чото или памнуть

                                    Мало того, что с пустыми скобочками это чище, так теперь вот я узнал, что это еще и дешевле)
                                    Ответить
                                • > гарантирует

                                  Короче почитала спеку, там немного хитрее.

                                  Лямбда это всегда класс, но в captureless случае у нее есть оператор каста в сишную функцию. Поэтому она так интуитивно и работает.
                                  Ответить
                                  • И типа ты ождиаешь функцию, компилятор видит, что туда передают объект, который неявно кастится в функцию, и кастит его?

                                    выходит, я могу и свой класс так сделать, не () у него реализовывать, а каст в функцию?
                                    Ответить
                    • Ну вот как Полина выше пишет -- представь, что это обычный класс с оператором скобки.

                      Т.е. можно даже указатель на код туда не ложить если полиморфизм не нужен.
                      Ответить
        • >Гомоиконы -- это лисп
          или XLST
          или TCL

          Много есть могучих языков
          Ответить
          • Или «Nim», но я не уверен, что там такое есть. Зато на «Nim» написали клон «Vim»!
            Ответить
          • XSLT -- да, наверное. Данные и код выглядят одинаково хуёво...

            А TCL подошёл из-за того, что и код и данные -- просто строки, которые он даже не парсит до запуска команды? Ну хотя там же квадратные скобочки есть, у которых нет аналога в виде данных... Про TCL я сомневаюсь, в общем.
            Ответить
            • >хуёво
              ой,ну ладно! а где у вас еще прямо в языке есть средства для навигации по дереву типа XQuery и XPath?:)

              Вы просто ненавидите XML!

              >а больше он ничего и не умеет
              ну да, там вроде еще массивы есть, но можно и без них.
              Ответить
              • > массивы

                А их вроде нет в синтаксисе, это просто команда?

                Ну вот [ ] как данные трактовать не получится, походу (они выполнятся). Только самому закавычить в { } и парсить как строку. Так что не чистая гомоиконщина получается.
                Ответить
                • >А их вроде нет в синтаксисе, это просто команда?
                  скобочки же круглые?

                  >Ну вот [ ] как данные трактовать не получится,
                  ну да, это как $() или ` `

                  Тем не менее, везде TCL туда причисляют
                  Ответить
      • сварщик что ли?
        Ответить
      • Машинный код гомоиконен

        Любой код это просто данные
        Почти любые данные это код (ну ладно, иногда это инвалид опкод)

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

        -----

        Главный враг гомокион это гарвардская архитектура: они даже память разделили)
        Ответить
        • Гарвардская архитектура никак не мешает компилтайм-гомоиконам. Она только в рантайме может мешать, если ты будешь набрасывать в процессе исполнения некий AST, делать из него инструкции процессора и исполнять его.

          А если у тебя интерпретируемая питушня, то и гарвардская архитектура нихрена мешать не будет, если ты конечно не захочешь переписать сам интерпретатор
          Ответить
          • Ну и всякий шитый код прекрасно работает на любой архитектуре, даже если нативный код совсем добавлять нельзя.

            Хотя это к интерпретаторам относится уже.
            Ответить
        • > Главный враг гомокион это гарвардская архитектура

          Емнип, была упоротая либа для эзернета для AVR, которая генерила код для отправки пакета на флешку, а потом исполняла его. При гарвардской архитектуре, да. По-другому этот проц просто не успевал.

          Т.е. раздельная память ещё не означает, что в неё вообще нельзя срать. Скорее просто неудобно или нецелесообразно.
          Ответить
          • Да, там есть инструкции чтоб срать в память для инструкций, только вот эта память является флешевой, и она от частой перезаписи быстро сдохнет. А вот под какие-то неизменяемые глобалки эту память вполне можно юзать, но читать ее тоже надо будет особыми говноинструкциями, а не как обычную оперативную память. Есть еще архитектуры, где память стекфреймов тоже как-то отдельно адресуется через какую-то сраную парашу, в Эльбрусах такую питушню вроде как делали. Там можно даже делать отдельную память для локальных переменных и отдельную память для адресов возврата, чтоб переполнением массива на стеке нельзя было в адрес возврата свою хуйню насрать с целью эксплоита
            Ответить
            • > для адресов возврата

              Ну такое... По идее любой указатель на стеке -- это потенциальный эксплойт при переполнении буфера. Не только адрес возврата.

              Да и с другими данными, возможно, что-то могут сделать. Хоть это и будет сложнее.

              З.Ы. Лучше какую-то аппаратную поддержку рейнджей прикрутить с двойными регистрами, чтобы буфера вообще не переполнялись. Интел пытался, кстати. Но получилась хуйня и её закопали.
              Ответить
              • > З.Ы. Лучше какую-то аппаратную поддержку рейнджей прикрутить с двойными регистрами, чтобы буфера вообще не переполнялись. Интел пытался, кстати. Но получилась хуйня и её закопали.

                Ну так такую хуйню в Эльбрусах как раз реализовали, можешь посмотреть например тут
                https://cyberleninka.ru/article/n/zaschischennoe-ispolnenie-programm-na-baze-apparatnoy-i-sistemnoy-podderzhki-arhitektury-elbrus/pdf


                > Разница между дескрипторами и обычными указателями заключается в том, что помимо адреса объекта в дескрипторе сохраняется некоторая дополнительная информация, существенная для защиты. Состав этой дополнительной информации зависит от типа объекта, на который ссылается дескриптор

                > Дескриптор массива кроме адреса начала массива содержит размер массива, и смещение относительно начала массива, соответствующее текущему значению указателя (рис. 1).
                Ответить
                • >Разница между дескрипторами и обычными указателями заключается в том, что помимо адреса объекта в дескрипторе сохраняется некоторая дополнительная информация, существенная для защиты. Состав этой дополнительной информации зависит от типа объекта, на который ссылается дескриптор



                  прямо как у виндовых объектов))

                  но было бы круто, если бы это было хардварно, и да: с размерами массива
                  Ответить
                  • Да, это можно сделать хардварно, и в Эльбрусах так сделали. Но лично я считаю эту идею хуйней т.к. даже хардварно это какие-то дополнительные расходы (дополнительная логика в процессоре, расход электричества и времени на эти говнопроверки).

                    А, ну еще есть https://en.wikipedia.org/wiki/Intel_MPX только вот софтварная проверка границ не оказывается более медленной:

                    > Even though Intel MPX is a specially designed hardware-assisted approach with its own added set of hardware registers, it is not faster than any of the software-based approaches. New Intel MPX instructions can cause up to 4× slowdown in the worst case, although compiler optimizations amortize it and lead to runtime overheads of ~50% on average.
                    Ответить
              • Вот еще https://habr.com/ru/post/214377/

                > После провала 432-ой машины весь мир бросил заниматься аппаратной поддержкой языков высокого уровня. Об этом забыли в районе 84-го года и до сих пор снова не вспомнили. Все считают, что это красивая идея, однако не практичная. Считают, несмотря на то, что у нас была полная реализация этой идеи, причём реализация эффективная.

                > Но к чему в итоге пришли языки высокого уровня? Все нынешние языки высокого уровня на две группы можно поделить: в одну входят языки типа Java, в другую – типа C. Java – это строгий контроль типов, но очень неэффективный. И динамики там нет. Никто даже не думает на Java операционную систему писать. По моим нормам, это не универсальный язык высокого уровня. Другая группа – С-подобные языки. Общее мнение таково, что это не языки высокого уровня. Скорее, вариант ассемблера.

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

                > Теперь, что же нужно для того, чтобы получить эти преимущества? Очень немного. Это легко сделать.

                > Прежде всего, в языках и аппаратуре вводится два типа дескрипторов – пространственные и временнЫе. Пространственный дескриптор – это, фактически, указатель на данные. Он может, например, содержать размер массива и адрес начала массива. Типичные операции с таким дескриптором – индексирование (доступ к конкретному элементу массива) и взятие подмассива. Всего существует очень небольшое количество операций над указателями на данные.

                > И важным моментом здесь является то, что базовый адрес для операций чтения и записи памяти может браться только с таких указателей. С их помощью аппаратура осуществляет контроль выхода за границу массива. О том, что ещё дают пространственные дескрипторы, я скажу позже, когда буду говорить о «контекстной защите».
                Ответить
                • ну блин, люди даже с хардварным переключением контекста обосрались, что уж о другом говорить

                  >аппаратной поддержкой языков высокого уровня. О
                  место для шутки про поддержку плавпитуха из JS в арме
                  Ответить
              • гдето в XMM есть поддержка clamped integers
                Ответить

    Добавить комментарий