Wandbox
SettingsLog
SettingsLog
Language
GitHubLogin
Ran/Viewed Log

Author

anonymous

less than a minute ago

Language

C

Compiler

gcc 13.2.0

Options
Warnings
C99
no pedantic

Author

anonymous

less than a minute ago

›
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>

/* aの下位8bit + bの下位8bit + c を計算する */
/* [OF][CF][和8bit] を返す */
int adc_asm(int a, int b, int c) {
int sum, flags;
__asm__ __volatile__ (
"test %4, %4\n\t" /* CF = 0 にする */
"jz 1f\n\t"
"stc\n" /* c != 0 ならば、CF = 1 にする */
"1:\n\t"
"adc %%dl, %%al\n\t"
"mov %%eax, %1\n\t"
"pushf\n\t"
"mov (%%rsp), %0\n\t"
"add $8, %%rsp\n\t"
: "=r"(flags), "=r"(sum) : "a"(a), "d"(b), "r"(c));
return (sum & 0xff) | (flags & 0x0800 ? 0x200 : 0) | (flags & 1 ? 0x100 : 0);
}

int adc(int a, int b, int c) {
int sum = (a & 0xff) + (b & 0xff) + c;
int overflow = (a & 0x80) == (b & 0x80) && (a & 0x80) != (sum & 0x80);
return (sum & 0x1ff) | (overflow ? 0x200 : 0);
}

/* aの下位8bit - (bの下位8bit + c) を計算する */
/* [OF][CF][差8bit] を返す */
int sbb_asm(int a, int b, int c) {
int diff, flags;
__asm__ __volatile__ (
"test %4, %4\n\t" /* CF = 0 にする */
"jz 1f\n\t"
"stc\n" /* c != 0 ならば、CF = 1 にする */
"1:\n\t"
"sbb %%dl, %%al\n\t"
"mov %%eax, %1\n\t"
"pushf\n\t"
"mov (%%rsp), %0\n\t"
"add $8, %%rsp\n\t"
: "=r"(flags), "=r"(diff) : "a"(a), "d"(b), "r"(c));
return (diff & 0xff) | (flags & 0x0800 ? 0x200 : 0) | (flags & 1 ? 0x100 : 0);
}

int sbb(int a, int b, int c) {
int diff = (a & 0xff) + (~b & 0xff) + !c;
int overflow = (a & 0x80) != (b & 0x80) && (a & 0x80) != (diff & 0x80);
return ((diff ^ 0x100) & 0x1ff) | (overflow ? 0x200 : 0);
}

int main(void) {
int a, b, c;
for (a = 0; a <= 0xff; a++) {
for (b = 0; b <= 0xff; b++) {
for (c = 0; c <= 1; c++) {
int r1 = adc_asm(a, b, c);
int r2 = adc(a, b, c);
int r3 = sbb_asm(a, b, c);
int r4 = sbb(a, b, c);
if (r1 != r2) {
printf("adc error (a, b, c) = (0x%02x, 0x%02x, %d) expected = 0x%03x, actual = 0x%03x\n", a, b, c, r1, r2);
}
if (r3 != r4) {
printf("sbb error (a, b, c) = (0x%02x, 0x%02x, %d) expected = 0x%03x, actual = 0x%03x\n", a, b, c, r3, r4);
}
}
}
}
return 0;
}

$ gcc prog.c -Wall -Wextra -std=c99
Exit Code:
0