scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit d9e4e31e2919820479baa822e9a7dd2d6ce3b43d
parent ef4381d70e872c9a64381859e31808df19c7a331
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 21 Sep 2019 19:50:40 +0200

[as-powerpc] Add BC instructions

These are conditional branch instructions

Diffstat:
Msrc/cmd/as/target/powerpc/ins.c | 27++++++++++++++++++++++++++-
Msrc/cmd/as/target/powerpc/powerpc.dat | 9+++++++++
Msrc/cmd/as/target/powerpc/rules.dat | 1+
Mtests/as/execute/powerpc.s | 5+++++
4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/cmd/as/target/powerpc/ins.c b/src/cmd/as/target/powerpc/ins.c @@ -79,6 +79,7 @@ match(Op *op, Node **args) if ((getclass(np) & class) == 0) return 0; break; + case AIMM5: case AIMM8: case AIMM16: case AIMM32: @@ -160,7 +161,31 @@ i_form(Op *op, Node **args) void b_form(Op *op, Node **args) { - abort(); + unsigned long ins, opcd, bo, bi, bd, aa, lk; + long long dst; + long long max = 1l << 13; + long long min = -(1l << 13); + + opcd = op->bytes[0]; + aa = op->bytes[1]; + lk = op->bytes[2]; + + bo = args[0]->sym->value; + bi = args[1]->sym->value; + + dst = args[2]->sym->value; + if (dst & 0x3) + error("unaligned branch"); + if (aa) + dst -= cursec->curpc - 4; + + if (dst < min || dst > max) + error("out of range branch"); + bd = dst; + bd >>= 2; + + ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk; + emit_packed(ins); } void diff --git a/src/cmd/as/target/powerpc/powerpc.dat b/src/cmd/as/target/powerpc/powerpc.dat @@ -45,3 +45,12 @@ BL imm32 4 18,0,1 i_form POWERPC BL imm64 4 18,0,1 i_form POWERPC64 BLA imm32 4 18,1,1 i_form POWERPC BLA imm64 4 18,1,1 i_form POWERPC64 + +BC imm5,imm5,imm32 4 16,0,0 b_form POWERPC +BC imm5,imm5,imm64 4 16,0,0 b_form POWERPC64 +BCA imm5,imm5,imm32 4 16,1,0 b_form POWERPC +BCA imm5,imm5,imm64 4 16,1,0 b_form POWERPC64 +BCL imm5,imm5,imm32 4 16,0,1 b_form POWERPC +BCL imm5,imm5,imm64 4 16,0,1 b_form POWERPC64 +BCLA imm5,imm5,imm32 4 16,1,1 b_form POWERPC +BCLA imm5,imm5,imm64 4 16,1,1 b_form POWERPC64 diff --git a/src/cmd/as/target/powerpc/rules.dat b/src/cmd/as/target/powerpc/rules.dat @@ -1,3 +1,4 @@ +imm5 AIMM5 imm8 AIMM8 imm16 AIMM16 imm32 AIMM32 diff --git a/tests/as/execute/powerpc.s b/tests/as/execute/powerpc.s @@ -2,3 +2,8 @@ BA $L1 / 48 00 00 0E BL $L1 / 48 00 00 0D L1: BLA $L1 / 48 00 00 07 + + BC $3,$2,$L2 / 40 62 38 00 + BCA $2,$1,$L2 / 40 41 18 02 + BCL $1,$3,$L2 / 40 23 38 01 +L2: BCLA $3,$4,$L2 / 40 64 08 03