Кресты / Говнокод #28003 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 digitalEugene, (Updated )

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

      • Лучше всего массив конечно, тогда можно за 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];
        }
        Ответить
        • Ни для кого не секрет, что человеческий организм при первой же возможности стремится избавиться от всех газов
          Ответить
  • Почему та самая инструкция про решение уравнений в полях Галуа не поддерживается?
    Ответить
    • не понял, почему так нельзя? 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'ы в голову не лезут.
        Ответить
        • Может это и есть инвалид опкод, просто чел заленится его в константну вынести?
          Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8