libc: тонкие аксессоры → inline в заголовках (по размерному критерию)

Inline (чистый C99 `inline` без static, паттерн из libbgi/5de2f06):
textattr, get_text_attr, get/set_putch_raw_mode (conio.h; g_text_attr
и pc_raw_mode объявлены публично), isatty (unistd.h — сворачивается в
константу при константном fd).  Модули удалены (5 шт).

«Толстые» кандидаты НЕ инлайнены — критерий проверен замером на 47
программах: feof/ferror/clearerr (тело ~12-15 байт с NULL-проверкой,
filetest +56 Б при инлайне) и textcolor/textbackground/set_text_attr
(RMW-маски, conio2 +13 Б) остаются модулями — при 2+ сайтах вызова
инлайн крупнее call+общее тело.  Правило: инлайнить только тела
<= ~6 байт на сайте или сворачиваемые константами.

Дельты: solidt -94, hello -24, mouse -7, bios_text -7; conio2 +11
(textattr×5 — паритет, принято за скорость).  z80.lib SDCC не содержит
feof/isatty — маскировки удалённых модулей нет, провал инлайна = ошибка
линковки.  Проверено в MAME: conio2 (атрибутная матрица), filetest
(полный прогон).  В size_baseline также вошли gfx_dbuf +608/gfx_demo
+25 — это первый чистый релинк run-рендера текста (ba09c0b), не inline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 21:53:37 +03:00
parent 5de2f06cfb
commit c9ac0999fd
10 changed files with 36 additions and 90 deletions
+11 -15
View File
@@ -1,5 +1,4 @@
# Эталон размеров _CODE (байт); обновление: python3 toolchain/size_check.py --update # Эталон размеров _CODE (байт); обновление: python3 toolchain/size_check.py --update
accfill 3963
argv 3431 argv 3431
assrtest 3847 assrtest 3847
attrprob 4091 attrprob 4091
@@ -7,42 +6,39 @@ banked 1056
bankedbg 1067 bankedbg 1067
banklocl 4832 banklocl 4832
banktest 3767 banktest 3767
bgi_img 5931 bios_text 4463
bgitest 4053
bios_text 4470
cat 915 cat 915
cblstream 6277
cbltest 6407 cbltest 6407
cblwav 6486 cblwav 6486
conio 4634 conio 4634
conio2 3946 conio2 3957
dec_test 860 dec_test 860
errno 6216 errno 6216
fbench 9040 fbench 9040
fdmax 6337 fdmax 6337
filetest 11624 filetest 11624
gets 509 gets 509
gfx_dbuf 4770 gfx_dbuf 5378
gfx_demo 4261 gfx_demo 4286
hello 4176 hello 4170
hello2 4251 hello2 4247
irqtest 5881 irqtest 5881
ls 4919 ls 4919
malloc 4462 malloc 4462
mdview 19122 mdview 19118
mdview2 27029 mdview2 27036
mem_test 4558 mem_test 4558
mouse 4394 mouse 4387
openenv 6127 openenv 6127
ptime 5896 ptime 5896
rt_test 4906 rt_test 4906
seek 4177 seek 4177
simple 963 simple 963
solidt 12381 solidt 12287
stattest 7700 stattest 7700
stdlib 6643 stdlib 6643
stest2 3644 stest2 3644
strtest 1340 strtest 1340
text_palette 5039 text_palette 5039
timedir 5471 timedir 5471
winrest 4481 winrest 4479
1 # Эталон размеров _CODE (байт); обновление: python3 toolchain/size_check.py --update
accfill
2 argv
3 assrtest
4 attrprob
6 bankedbg
7 banklocl
8 banktest
9 bgi_img bios_text
bgitest
bios_text
10 cat
cblstream
11 cbltest
12 cblwav
13 conio
14 conio2
15 dec_test
16 errno
17 fbench
18 fdmax
19 filetest
20 gets
21 gfx_dbuf
22 gfx_demo
23 hello
24 hello2
25 irqtest
26 ls
27 malloc
28 mdview
29 mdview2
30 mem_test
31 mouse
32 openenv
33 ptime
34 rt_test
35 seek
36 simple
37 solidt
38 stattest
39 stdlib
40 stest2
41 strtest
42 text_palette
43 timedir
44 winrest
+2 -6
View File
@@ -20,17 +20,13 @@
#include <conio.h> /* two_bytes, KEEP_EXIST_ATTR */ #include <conio.h> /* two_bytes, KEEP_EXIST_ATTR */
#include <stdint.h> #include <stdint.h>
/* Текущий текстовый атрибут: 0x00..0xFF — реальный байт атрибута, /* g_text_attr (текущий атрибут) и pc_raw_mode объявлены в ПУБЛИЧНОМ
* KEEP_EXIST_ATTR (0xFFFF) — быстрый путь без атрибута. */ * conio.h (нужны inline-аксессорам textcolor/textattr/…, 2026-07-10). */
extern two_bytes g_text_attr;
/* Позиция курсора: .byte.low = col, .byte.high = row. /* Позиция курсора: .byte.low = col, .byte.high = row.
* Поддерживается gotoxy/wherex/wherey/wherexy и воркерами putch. */ * Поддерживается gotoxy/wherex/wherey/wherexy и воркерами putch. */
extern two_bytes pc_place; extern two_bytes pc_place;
/* 0 — BS/TAB/LF/CR интерпретируются; 1 — печатаются как глифы. */
extern uint8_t pc_raw_mode;
/* Прочитать курсор BIOS (rst 8, $8E) в pc_place. */ /* Прочитать курсор BIOS (rst 8, $8E) в pc_place. */
void _get_cursor(void); void _get_cursor(void);
-11
View File
@@ -1,11 +0,0 @@
/*
* get_putch_raw_mode — текущий режим обработки управляющих символов
* putch/cputs (см. set_putch_raw_mode).
*/
#include "_conio.h"
uint8_t get_putch_raw_mode(void)
{
return pc_raw_mode;
}
-10
View File
@@ -1,10 +0,0 @@
/*
* get_text_attr — текущий 16-битный атрибут conio (см. set_text_attr).
*/
#include "_conio.h"
int16_t get_text_attr(void)
{
return g_text_attr.value;
}
-12
View File
@@ -1,12 +0,0 @@
/*
* set_putch_raw_mode — режим обработки управляющих символов в
* putch/cputs: 0 — BS/TAB/LF/CR интерпретируются, 1 — все байты
* печатаются как глифы CP437 (см. pc_raw_mode).
*/
#include "_conio.h"
void set_putch_raw_mode(uint8_t mode)
{
pc_raw_mode = mode;
}
-11
View File
@@ -1,11 +0,0 @@
/*
* textattr — заменить атрибут целиком одним байтом (fg | bg | blink).
* Turbo-C-стиль. Сбрасывает KEEP_EXIST_ATTR (старший байт = 0).
*/
#include "_conio.h"
void textattr(uint8_t attr)
{
g_text_attr.value = (uint16_t)attr;
}
+16 -5
View File
@@ -160,12 +160,23 @@ int settextmode(uint8_t mode); /* 0 OK, -1 + errno on bad mode */
* ------------------------------------------------------------------ */ * ------------------------------------------------------------------ */
#define KEEP_EXIST_ATTR 0xFFFF #define KEEP_EXIST_ATTR 0xFFFF
/* Внутреннее состояние (хранилище: libc/conio/_g_text_attr.c и
* _pc_raw_mode.c) — НЕ трогать напрямую, только через функции ниже.
* Объявлено здесь, чтобы ТОНКИЕ аксессоры были inline: чистый C99
* `inline` БЕЗ static — SDCC инлайнит вызов и не эмитит standalone-
* тело (см. memory/sdcc_inline_codegen_findings). «Толстые» (RMW-
* маски textcolor/textbackground, set_text_attr с возвратом прежнего)
* НЕ inline — замерено: тело 12+ байт при 2+ сайтах вызова крупнее
* call+общее тело (conio2 +13 Б). */
extern two_bytes g_text_attr;
extern uint8_t pc_raw_mode;
void textcolor(uint8_t fg); void textcolor(uint8_t fg);
void textbackground(uint8_t bg); void textbackground(uint8_t bg);
void textattr(uint8_t attr); inline void textattr(uint8_t attr) { g_text_attr.value = (uint16_t)attr; }
int16_t set_text_attr(int16_t attr); /* returns the previous value */ int16_t set_text_attr(int16_t attr); /* возвращает прежнее значение */
int16_t get_text_attr(void); inline int16_t get_text_attr(void) { return g_text_attr.value; }
/* Control how putch / cputs / cprintf (the WRCHAR path) treat /* Control how putch / cputs / cprintf (the WRCHAR path) treat
* control characters (< 0x20): * control characters (< 0x20):
@@ -183,8 +194,8 @@ int16_t get_text_attr(void);
* Only affects the WRCHAR path (attr ≤ 0xFF). When attr is * Only affects the WRCHAR path (attr ≤ 0xFF). When attr is
* KEEP_EXIST_ATTR, ESTEX's own PUTCHAR/PCHARS rule the cursor and * KEEP_EXIST_ATTR, ESTEX's own PUTCHAR/PCHARS rule the cursor and
* pc_raw_mode is irrelevant. */ * pc_raw_mode is irrelevant. */
void set_putch_raw_mode(uint8_t mode); inline void set_putch_raw_mode(uint8_t mode) { pc_raw_mode = mode; }
uint8_t get_putch_raw_mode(void); inline uint8_t get_putch_raw_mode(void) { return pc_raw_mode; }
/* Sprinter text-mode 03h attribute byte (verified via attr_probe): /* Sprinter text-mode 03h attribute byte (verified via attr_probe):
* bits 0..3 = foreground (0..15) * bits 0..3 = foreground (0..15)
+2
View File
@@ -122,6 +122,8 @@ void rewind(FILE *fp);
int fgetpos(FILE *fp, fpos_t *pos); int fgetpos(FILE *fp, fpos_t *pos);
int fsetpos(FILE *fp, const fpos_t *pos); int fsetpos(FILE *fp, const fpos_t *pos);
/* НЕ inline (замерено 2026-07-10, filetest +56 Б): тело с NULL-проверкой
* ~12-15 байт — при 2+ сайтах вызова инлайн крупнее call+общее тело. */
int feof (FILE *fp); int feof (FILE *fp);
int ferror(FILE *fp); int ferror(FILE *fp);
void clearerr(FILE *fp); void clearerr(FILE *fp);
+3 -2
View File
@@ -34,8 +34,9 @@ void sleep(unsigned int seconds);
void delayms(uint16_t ms); void delayms(uint16_t ms);
/* 1, если fd — консоль (наши псевдо-fd 0/-1/-2), 0 — файл (любой /* 1, если fd — консоль (наши псевдо-fd 0/-1/-2), 0 — файл (любой
* положительный манипулятор DSS; из командной строки они идут с 1). */ * положительный манипулятор DSS; из командной строки они идут с 1).
int isatty(int fd); * inline без static — см. memory/sdcc_inline_codegen_findings. */
inline int isatty(int fd) { return fd <= 0; }
/* Directory operations (ESTEX $1B-$1E). All return 0 on success and -1 /* Directory operations (ESTEX $1B-$1E). All return 0 on success and -1
* with errno set on failure; getcwd returns the buffer on success or NULL. * with errno set on failure; getcwd returns the buffer on success or NULL.
-16
View File
@@ -1,16 +0,0 @@
/*
* isatty — 1, если fd указывает на консоль, 0 — на файл.
*
* Консольные псевдо-fd наших stdin/stdout/stderr: 0, -1, -2
* (см. libc/file/std_streams.c). Все положительные fd — файловые
* манипуляторы DSS: из командной строки DSS нумерация начинается
* с 1, под Flex Navigator — с 2 (fd 1 держит сам навигатор), т.е.
* fd == 1 может быть обычным файлом.
*/
#include <unistd.h>
int isatty(int fd)
{
return fd <= 0;
}