#LC3 Trying to Subtract two number, but the result comes out is not correct - lc3

MySUB NOT R4,R3 | Flip R3 and load into r4
ADD R1,R4,#1 | ADD R4 with 1 and load into r1
ADD R3,R2,R1 | ADD R4 with R1 and load into R3
RET |Output R3
So R2 and R3 it's given in the data, and r3's value is the output value.
My output:
009-001=008
004+004=008
008+002=010
003+002=005
001+000=001
005+001=006
009+003=012
008+004=012
000+000=000
002+001=003
The Output should look like:
009-001=008
004-004=000
008-002=006
003-002=001
001-000=001
005-001=004
009-003=006
008-004=004
000-000=000
002-001=001

Related

Is this a GCC bug or am I doing something wrong?

I am trying to get the final accumulate in the code below to use the ARM M7 SMLAL 32*32->64 bit accumulate function. If I include the T3 = T3 + 1 than it does use this, but if I comment it out it does a full 64*64 bit and accumulate using 3 multiply and 2 add instructions. I don't actually want to add 1 to T3 so it needs to go.
I've broken the code down so that I could analyse it in more detail and it definitely seems to be that the cast of T3 to int32_t and throwing away the bottom 32 bits from the multiply isn't being picked up by the compiler and it thinks T3 still has 64 bits. Bit when I add the simple increment of T3 it then gets it correct. I tried adding zero but then it goes back to the full 64*64 bit multiply.
I'm using the -O2 optimisation on STM's STM32CubeIDE which uses a version of GCC. Other optimations never use SMLAL or unroll everything.
int64_t T4 = 0;
osc = key * NumHarmonics;
harmonic = 0;
do
{
if (OscLevel[osc] > 1)
{
OscPhase[osc] = OscPhase[osc] + (uint32_t)(T2);
int32_t T5 = Sine[(OscPhase[osc] >> 16) & 0x0000FFFF];
int64_t T6 = (int64_t)T1 * Tremelo[harmonic];
int32_t T3 = (int32_t)(T6 >> 32); // grab the most significant register
// T3 = T3 + 1; // needs the +1 to force use of SMLAL in next instruction ! (+0 doesn't help)
T4 = T4 + (int64_t)T3 * (int64_t)T5; // should be SMLAL but does a full 64*64 mult if no +1 above
}
osc++;
harmonic++;
}
while (harmonic < NumHarmonics);
OscTotal = T4;
without the addition :
800054e: 4b13 ldr r3, [pc, #76] ; (800059c <main+0xd8>)
8000550: f853 1024 ldr.w r1, [r3, r4, lsl #2]
8000554: ea4f 79e1 mov.w r9, r1, asr #31
8000558: fba7 4501 umull r4, r5, r7, r1
800055c: fb07 f309 mul.w r3, r7, r9
8000560: fb01 3202 mla r2, r1, r2, r3
8000564: 4415 add r5, r2
8000566: e9dd 2300 ldrd r2, r3, [sp]
800056a: 1912 adds r2, r2, r4
800056c: 416b adcs r3, r5
800056e: e9cd 2300 strd r2, r3, [sp]
}
osc++;
8000572: 3001 adds r0, #1
harmonic++;
with the addition
8000542: 4b0b ldr r3, [pc, #44] ; (8000570 <main+0xac>)
8000544: f853 3020 ldr.w r3, [r3, r0, lsl #2]
8000548: fbc3 6701 smlal r6, r7, r3, r1
}
osc++;
800054c: 3201 adds r2, #1
harmonic++;

Gcc Plugin - Adding a label to the generated assembly

I'm trying to use a plugin to generate a label with the following code:
tree lab = build_decl (gimple_location (gsi_stmt (gsi)),
LABEL_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (lab) = 0;
DECL_IGNORED_P (lab) = 1;
DECL_CONTEXT (lab) = current_function_decl;
DECL_NAME(lab) = get_identifier("test_text");
location_t loc = gimple_location (gsi_stmt (gsi));
tree label = create_artificial_label (loc);
gsi_insert_before (&gsi, gimple_build_label (lab), GSI_SAME_STMT);
While this works when I try to generate code for my intel processor, if I run this plugin in a cross-compiler for arm the labels' names are changed to a local symbol with a random name. For example, instead of obtaining "test_text:" I get ".L4:". Also, an additional instruction is added.
Below is an example of the code generated without the label generation code enabled.
ldrb r3, [fp, #-5] # zero_extendqisi2
add r2, r2, r3
movw r3, #:lower16:b1
movt r3, #:upper16:b1
str r2, [r3, #4]
And now, it follows the code generated using the first shown code (generating a label in the tree and gimple representations). You can see that the test_text label was subsituted by .L5 and that an add instruction was added below the label. How is this possible?
ldrb r3, [fp, #-5] # zero_extendqisi2
add r2, r2, r3
.L5:
add fp, fp, #4
movw r3, #:lower16:b1
movt r3, #:upper16:b1
str r2, [r3, #4]
I'm running my plugin after the CFG pass. Also, I'm using Linaro cross-compiler arm-eabi-gcc version 6.3.1.
Best Regards
Edit 1:
Also found, by using -fdump-tree-optimized, that until this stage everything is fine. Partial output of the *.optmized file:
<bb 4>:
_8 = i_2 % 3;
_9 = _8 == 0;
test_text:
div_3 = _9;
_11 = i_2 % 5;

With only ADD, AND, NOT How do we OR

In LC-3, how can I store r1 or r2 into register r3
ld r1, a ;move the value of a into r1
ld r2, b ;move the value of b into r2
and r3, r1, r2 ;
halt ;stop
You can use DeMorgan's law to achieve this.
X ∨ Y = ¬(¬X ∧ ¬Y)
In LC3 code it's:
LD R1, a ;move the value of a into R1
LD R2, b ;move the value of b into R2
NOT R1, R1
NOT R2, R2
AND R3, R1, R2
NOT R3, R3
HALT

LC3 trap executed illegal vector number

I'm trying to count the number of characters in LC3 simulator and keep getting "a trap was executed with an illegal vector number".
These are the objects I execute
charcount.obj:
0011000000000000
0101010010100000
0010011000010000
1111000000100011
0110001011000000
0001100001111100
0000010000001000
1001001001111111
0001001001100001
0001001001000000
0000101000000001
0001010010100001
0001011011100001
0110001011000000
0000111111110110
0010000000000100
0001000000000010
1111000000100001
1111000000100101
1110001011111111
0000000000110000
and verse:
.ORIG x3100
.STRINGZ "Simple Simon met a pieman,"
.STRINGZ "Going to the fair;"
.STRINGZ "Says Simple Simon to the pieman,"
.STRINGZ "Let me taste your ware."
.FILL x04
.END
Looks like we're going to need more information before we can help you much. I understand you've provided us with some binary and I ran that through the LC3 simulator. Here's where I'm a bit lost, which string would you like to count and where is it stored?
After trying to piece together what you've provided here's what I've found.
Registers:
R0 x0061 97
R1 x0000 0
R2 x0000 0
R3 xE2FF -7425
R4 x0000 0
R5 x0000 0
R6 x0000 0
R7 x3003 12291
PC x3004 12292
IR x62C0 25280
CC Z
Memory:
x3000 0101010010100000 x54A0 AND R2, R2, #0
x3001 0010011000010000 x2610 LD R3, x3012
x3002 1111000000100011 xF023 TRAP IN
x3003 0110001011000000 x62C0 LDR R1, R3, #0
x3004 0001100001111100 x187C ADD R4, R1, #-4
x3005 0000010000001000 x0408 BRZ x300E
x3006 1001001001111111 x927F NOT R1, R1
x3007 0001001001100001 x1261 ADD R1, R1, #1
x3008 0001001001000000 x1240 ADD R1, R1, R0
x3009 0000101000000001 x0A01 BRNP x300B
x300A 0001010010100001 x14A1 ADD R2, R2, #1
x300B 0001011011100001 x16E1 ADD R3, R3, #1
x300C 0110001011000000 x62C0 LDR R1, R3, #0
x300D 0000111111110110 x0FF6 BRNZP x3004
x300E 0010000000000100 x2004 LD R0, x3013
x300F 0001000000000010 x1002 ADD R0, R0, R2
x3010 1111000000100001 xF021 TRAP OUT
x3011 1111000000100101 xF025 TRAP HALT
x3012 1110001011111111 xE2FF LEA R1, x3112
x3013 0000000000110000 x0030 NOP
The values displayed in the registers is what I get when I stop after line x3003. For some reason the literal value of xE2FF gets loaded into register R3. After that the value of 0 at memory location xE2FF is loaded into register R1 and then the problems mount from there.
I would recommend displaying your asm code and then commenting each line so we can better understand what you're trying to accomplish.

LC3, Store a Value of a Register to a Memory Location

I'm attempting to write a short LC-3 program that initializes R1=5, R2=16 and computes the sum of R1 and R2 and put the result in memory x4000. The program is supposed to start at x3000. Unfortunately, I have to write it in binary form.
This is what I have so far...
.orig x3000__________; Program starts at x3000
0101 001 001 1 00000 ;R1 <- R1 AND x0000
0001 001 001 1 00101 ;R1 <- R1 + x0005
0101 010 010 1 00000 ;R2 <- R2 AND x0000
0001 010 010 1 01000 ;R2 <- R2 + x0008
0001 010 010 1 01000 ;R2 <- R2 + x0008
0001 011 010 0 00 001 ;R3 <- R2 + R1
//This last step is where I'm struggling...
I was thinking of using ST, and I figured PCOFFSET9 to be 994, but I can't represent that using 8 bits... so how else would I do this? Is my code inefficient?
0011 011
The ST command is limited to only 511 (I believe) from its current location in memory. For something like this you will need to use the STI command (Store Indirect) The sample code below will help explain how to use STI.
.orig x3000
AND R1, R1, #0 ; Clear R1
ADD R1, R1, #5 ; Store 5 into R1
AND R2, R2, #0 ; Clear R2
ADD R2, R2, #8 ; Store 8 into R2
ADD R3, R2, R1 ; R3 = R2 + R1
STI R3, STORE_x4000 ; Store the value of R3 into mem[x4000]
HALT ; TRAP x25 end the program
; Variables
STORE_x4000 .FILL x4000
.END
You will need to make the appropriate conversions to binary, but if you plug the code into the LC-3 simulator it will give you the binary representation.

Resources