Skip to content

Conversation

@samek-h
Copy link
Contributor

@samek-h samek-h commented Jan 23, 2026

A pull request created in response to #1304 that fixes the incorrect order of the rdtsc instruction output registers.

Reproduced using following program:

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
with System.Machine_Code; use System.Machine_code;

procedure Rdtsc is
   function Get_Processor_Cycles return Unsigned_64 is
      Low, High : Unsigned_32;
      Counter   : Unsigned_64;
   begin
      Asm ("rdtsc",
           Outputs =>
             (Unsigned_32'Asm_Output ("=a", High),  -- Incorrect
              Unsigned_32'Asm_Output ("=d", Low)),  -- Incorrect
           Volatile => True);

      Counter :=
         Unsigned_64 (High) * 2 ** 32 +
         Unsigned_64 (Low);

      return Counter;
   end Get_Processor_Cycles;
begin
   Put_Line ("tsc =" & Get_Processor_Cycles'Image);
end Rdtsc;

The resulting rdtsc value is seemingly random, not increasing:

$ taskset -c 0 ./rdtsc
tsc = 14729149879850896313
$ taskset -c 0 ./rdtsc
tsc = 7769122674801904570
$ taskset -c 0 ./rdtsc
tsc = 17445020729480317882
$ taskset -c 0 ./rdtsc
tsc = 8327487355497745339
$ taskset -c 0 ./rdtsc
tsc = 1353739439335017404

The same program, but using the correct order:

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
with System.Machine_Code; use System.Machine_code;

procedure Rdtsc is
   function Get_Processor_Cycles return Unsigned_64 is
      Low, High : Unsigned_32;
      Counter   : Unsigned_64;
   begin
      Asm ("rdtsc",
           Outputs =>
             (Unsigned_32'Asm_Output ("=a", Low),
              Unsigned_32'Asm_Output ("=d", High)),
           Volatile => True);

      Counter :=
         Unsigned_64 (High) * 2 ** 32 +
         Unsigned_64 (Low);

      return Counter;
   end Get_Processor_Cycles;
begin
   Put_Line ("tsc =" & Get_Processor_Cycles'Image);
end Rdtsc;

The resulting values are now increasing:

$ taskset -c 0 ./rdtsc
tsc = 13377973989561
$ taskset -c 0 ./rdtsc
tsc = 13381489237427
$ taskset -c 0 ./rdtsc
tsc = 13384125133819
$ taskset -c 0 ./rdtsc
tsc = 13386827400627
$ taskset -c 0 ./rdtsc
tsc = 13389239550049

@CLAassistant
Copy link

CLAassistant commented Jan 23, 2026

CLA assistant check
All committers have signed the CLA.

@samek-h samek-h marked this pull request as ready for review January 28, 2026 19:02
@gusthoff gusthoff self-requested a review January 30, 2026 16:36
@gusthoff gusthoff added the bug Something isn't working label Jan 30, 2026
@gusthoff gusthoff linked an issue Jan 30, 2026 that may be closed by this pull request
Copy link
Collaborator

@gusthoff gusthoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @samek-h,

Thanks a lot for not only reporting the issue, but also fixing it and even including and a reproducer! This is very much appreciated.

@gusthoff gusthoff merged commit 35c6867 into AdaCore:main Jan 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rdtsc register order incorrect

3 participants