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

    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
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    #define OPCODEFORMAT_CASE(opcode, format) case opcode: return format; break
    inline OpcodeFormat getOpcodeFormat(Opcode opcode)
    {
    	switch (opcode)
    	{
    		OPCODEFORMAT_CASE(NOP		, OPCODE);
    		OPCODEFORMAT_CASE(MOV_RR	, OPCODE_RR);
    		OPCODEFORMAT_CASE(MOV_RC	, OPCODE_RC);
    		OPCODEFORMAT_CASE(MOV_RM	, OPCODE_RM);
    		OPCODEFORMAT_CASE(MOV_MR	, OPCODE_MR);
    		OPCODEFORMAT_CASE(MOV_MC	, OPCODE_MC);
    		OPCODEFORMAT_CASE(MOV_MM	, OPCODE_MM);
    		OPCODEFORMAT_CASE(ADD		, OPCODE_RR);
    		OPCODEFORMAT_CASE(SUB		, OPCODE_RR);
    		OPCODEFORMAT_CASE(ADD_C	, OPCODE_RC);
    		OPCODEFORMAT_CASE(SUB_C		, OPCODE_RC);
    		OPCODEFORMAT_CASE(MUL		, OPCODE_RR);
    		OPCODEFORMAT_CASE(DIV		, OPCODE_RR);
    		OPCODEFORMAT_CASE(MUL_C	, OPCODE_RC);
    		OPCODEFORMAT_CASE(DIV_C		, OPCODE_RC);
    		OPCODEFORMAT_CASE(LEA		, OPCODE_RM);
    		OPCODEFORMAT_CASE(INC		, OPCODE_R);
    		OPCODEFORMAT_CASE(DEC		, OPCODE_R);
    		OPCODEFORMAT_CASE(INT		, OPCODE_C8);
    		OPCODEFORMAT_CASE(CMP_RC	, OPCODE_RC);
    		OPCODEFORMAT_CASE(JMP		, OPCODE_C);
    		OPCODEFORMAT_CASE(JZ		        , OPCODE_C);
    		OPCODEFORMAT_CASE(JNZ		, OPCODE_C);
    		OPCODEFORMAT_CASE(JG		, OPCODE_C);
    		OPCODEFORMAT_CASE(JNG		, OPCODE_C);
    		OPCODEFORMAT_CASE(JGZ		, OPCODE_C);
    		OPCODEFORMAT_CASE(JL		        , OPCODE_C);
    		OPCODEFORMAT_CASE(CALL		, OPCODE_C);
    		OPCODEFORMAT_CASE(PUSH_R	, OPCODE_R);
    		OPCODEFORMAT_CASE(PUSH_C	, OPCODE_C);
    		OPCODEFORMAT_CASE(PUSH_C8	, OPCODE_C8);
    		OPCODEFORMAT_CASE(POP_R	, OPCODE_R);
    		OPCODEFORMAT_CASE(POP		, OPCODE);
    		OPCODEFORMAT_CASE(POP8		, OPCODE);
    		OPCODEFORMAT_CASE(POP_M8	, OPCODE_M);
    		OPCODEFORMAT_CASE(POP_M16	, OPCODE_M);
    		OPCODEFORMAT_CASE(OUT_M8	, OPCODE_MC);
    		OPCODEFORMAT_CASE(OUT_M16	, OPCODE_MC);
    		OPCODEFORMAT_CASE(OUT_C8	, OPCODE_CC8);
    		OPCODEFORMAT_CASE(OUT_C16	, OPCODE_CC);
    		OPCODEFORMAT_CASE(OUT_R	, OPCODE_RC);
    		OPCODEFORMAT_CASE(IN_R		, OPCODE_RC);
    		OPCODEFORMAT_CASE(IN_M8	, OPCODE_MC);
    		OPCODEFORMAT_CASE(IN_M16	, OPCODE_MC);
    		OPCODEFORMAT_CASE(RET		, OPCODE);
    
    	default: return (OpcodeFormat)0xFF; break;
    	}
    }
    #undef OPCODEFORMAT_CASE

    отрефакторил

    Запостил: digitalEugene, 10 Февраля 2022

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

    • https://en.cppreference.com/w/cpp/container/map
      Ответить
      • Тут лучше либо хэшмапа, либо одномерный массив, индексирующийся опкодами.
        Ответить
        • Если у него опкодов немного можно тупо массив хуйнуть.
          Ответить
        • Лучше всего массив конечно, тогда можно за O(1) находить.
          Ответить
          • Надо ещё глянуть, во что этот свич конпелируется. А то поди массив и есть.
            Ответить
            • В легкую может, если компилятор умный. А даже если O1 не получится (например, там значения опкодов 1, 924 и 65532) то можно всё равно их сортирнуть, и бинарным поиском быстроенько найти
              Ответить
              • Ну я о том, будет ли он генерить массив из указателей на код, или же догадается просто значения туда сложить.

                Так то да, гцц насколько помню три варианта умеет для свича -- двоичный поиск (если мало и неплотно), одноуровневый массив (много и плотно) и двухуровневый массив (не очень плотно и повторяются).
                Ответить
        • кстати няшная победила. опять.
          enum OpcSrc
          {
          	MOV_RR,
          	MOV_RC
          };
          enum OpcType
          {
          	OPCODE_RR,
          	OPCODE_RC,
          };
          
          int main(void)
          {
          	enum OpcType opctable[] = 
          	{
          		[MOV_RR] = OPCODE_RR,
          		[MOV_RC] = OPCODE_RC
          	};
          	return opctable[MOV_RC];
          }
          Ответить
          • Ни для кого не секрет, что человеческий организм при первой же возможности стремится избавиться от всех газов
            Ответить
            • Ты в игноре, дурачёк.
              Ответить
              • > Ты в игноре, дурачёк.
                Шок! Вореции спасают от заражения омикроном.
                Ответить
                • Не отвечай уёбку, дурачёк.
                  Ответить
                • я ни разу не болел ковидом
                  Ответить
                  • Всё ещё впереди, кися. Мы с тобой познакомимся в интимной обстановке, например, на похоронах твоего самого близкого друга или родного.
                    Ответить
                    • благо у меня никого нет.
                      Ответить
                      • Теперь есть спермор, которого ты раскормил.
                        Ответить
                        • Ремонт будет хороший, если дизайнер - итальяшка, а рабочие - югославы
                          Ответить
                      • плохо. очень плохо, юноша!
                        Кто же подаст тебе чашку воды, запить эвтаназионный препарат, перед смертью?
                        Ответить
            • i fart in ur general direction
              Ответить
    • Почему та самая инструкция про решение уравнений в полях Галуа не поддерживается?
      Ответить
    • > (OpcodeFormat)0xFF

      Какой UB )))
      Ответить
      • не понял, почему так нельзя? OpcodeFormat это один signed байт?
        Ответить
        • Скажем так, у меня нет уверенности, что в енум можно безнаказанно пихать произвольную срань. Может быть это и не UB.

          Кобенации флажков в духе Value1 | Value2, насколько я понимаю, не противоречат стандарту. А вот что-то более длинное -- хрен бы знал, там очень сложная формулировка про underlying type и я её до конца не понимаю.
          Ответить
          • А где сказано, что это enum?


            Чисто технически enum вряд-ли занимает меньше байта, так что ничего убийственного не должно случиться (хотя если это реально UB, то компилятор просто выкинет всё нахуй, и дело с концом)
            Ответить
            • > выкинет всё нахуй

              Всё не выкинет, но у меня сомнения насчёт switch. К примеру, вдруг конпелятор посчитает, что раз у енума всего 2 варианта и underlying type явно не указан, то можно проверять их как "0 и не 0"? И 0xFF уйдёт в ветку с "не 0".

              9.7.1 Enumeration declarations

              8. For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, the values of the enumeration are the values representable by a hypothetical integer type with minimal width M such that all enumerators can be represented.
              Ответить
              • я имеел виду, что выкинет
                default: return (OpcodeFormat)0xFF; break;
                и будет там мусор в возвращаемом значении

                Так как ты определил тип OpcodeFormat?


                > hypothetical
                integer type with minimal width M such that all enumerators can be represented.

                Ну то есть там омжет быть signed char, например? И вот, 0xFF будет какашкаокок
                Ответить
                • Ну да, если представить, что опкодов немного и не все биты поюзаны, то minimal width может быть, к примеру, 5-6. И пихая туда 0xFF мы наступаем на тонкий лёд.

                  С другой стороны, если мы явно указали underlying type и 0xFF в него помещается, то вроде всё норм.
                  Ответить
                  • Я вообще не ебу что это за асрембелр такой. Если это x86, то там овердохуя опкодов, и они нихуя не один байт:) Какой там вообще андерлайн тайп нужен?
                    Ответить
                    • Здесь не опкоды, а форматы опкодов всё-таки. А их даже у х86 не очень много.
                      Ответить
                      • То есть тут будет составной опкод из нескольких кодов если что?
                        Ответить
            • 7.6.1.8 Static cast

              10. <...> If the enumeration type does not have a fixed underlying type, the value is unchanged if the original value is within the range of the enumeration values (9.7.1), and otherwise, the behavior is undefined. <...>
              Ответить
              • То есть можно и не кастовать вовсе:) Либо ты влез в значение, и ничего не изменится, или не влез, и тогда уб. или оно без касты не скопилица?

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

                  > не должен представлять енумы в виде цифр

                  Ну почему, если явно указать underlying type для енума, то всё будет норм. Главное за его пределы не вылетать.

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

                      Ты из файла прочитал 0x80, но такой маски в енуме ещё не было. Но т.к. ты указал тип явно (например uint8_t), то всё будет норм, просто незнакомый флаг не обработается. UB'а не будет.
                      Ответить
        • Даже если это технически не UB, то почему бы не добавить OPCODE_INVALID в OpcodeFormat? Пусть даже он там внутри будет 0xFF для бинарной совместимости. И читать легче и лишние мысли про UB'ы в голову не лезут.
          Ответить
          • Может это и есть инвалид опкод, просто чел заленится его в константну вынести?
            Ответить
          • оно из свитча не вылезет
            Ответить

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